Skip to content

Instantly share code, notes, and snippets.

@servel333
Last active December 23, 2015 13:19
Show Gist options
  • Save servel333/6641047 to your computer and use it in GitHub Desktop.
Save servel333/6641047 to your computer and use it in GitHub Desktop.
A method of extending the Array class without polluting the global namespace.
// http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/
(function(window, undefined) {
"use strict";
var _extend = function() {
var a = [ ];
args = Array.prototype.slice.call(arguments);
a.push.apply(a, args);
var noop = function(){};
a.is$Array = true;
a.first = function() { return this[0]; };
a.last = function() { return this[this.length - 1]; };
a.clone = function() { return _extend(a.slice(0)); };
/**
* @param on_item function(index, item)
* @param index The array index of the current item.
* @param item The value of the current item.
* @returns when on_item returns false, returns the index of the last item
* iterated; otherwise returns null.
*/
a.each = function(on_item) {
for (var i = 0; i < this.length; i++) {
if (on_item(i, this[i])) {
return i;
}
}
return null;
};
a.getNext = function(index, on_next) {
on_next = on_next || noop;
if (index >= 0 && index < this.length - 1) {
on_next(index+1, this[index+1]);
return index+1;
}
return null;
};
a.map = function(on_item) {
on_item = on_item || function(i,v) { return v; };
var new_array = _extend();
this.each(function(i,v) {
new_array.push(on_item(i,v));
});
return new_array;
};
a.select = function(on_condition) {
on_condition = on_condition || function(i,v) { return !!v; };
var new_array = _extend();
this.each(function(i,v) {
if (on_condition(i,v)) {
new_array.push(v);
}
});
return new_array;
};
a.contains = function(needle) {
return null !== this.each(function(i,v) {
return v == needle;
});
};
a.uniq = function() {
var new_array = _extend();
this.each(function(i,v) {
if (!new_array.contains(v)) {
new_array.push(v);
}
});
return new_array;
};
a.flatten = function() { return _extend(Array.prototype.concat.apply([], this)); };
// http://stackoverflow.com/questions/1427608/fast-stable-sorting-algorithm-implementation-in-javascript
a.msort = function(compare) {
var length = this.length,
middle = Math.floor(length / 2);
if (!compare) {
compare = function(left, right) {
if (left < right) return -1;
if (left == right) return 0;
else return 1;
};
}
if (length < 2) return this;
return array_msort.merge(
array_msort( Array.prototype.slice.call(this, 0, middle), compare ),
array_msort( Array.prototype.slice.call(this, middle, length), compare ),
compare
);
};
a.msort.merge = function(left, right, compare) {
var result = _extend();
while (left.length > 0 || right.length > 0) {
if (left.length > 0 && right.length > 0) {
if (compare(left[0], right[0]) <= 0) {
result.push(left[0]);
left = left.slice(1);
}
else {
result.push(right[0]);
right = right.slice(1);
}
}
else if (left.length > 0) {
result.push(left[0]);
left = left.slice(1);
}
else if (right.length > 0) {
result.push(right[0]);
right = right.slice(1);
}
}
return result;
};
return a;
};
var $Array = function(opt_Array) {
if (opt_Array === undefined) { return _extend(); }
if (opt_Array.is$Array) { return opt_Array.clone(); }
return _extend(opt_Array);
};
$Array.isArray = function(a) {
if (typeof Array.isArray === 'function') return Array.isArray( a );
//return a instanceof Array;
return Object.prototype.toString.call( a ) === '[object Array]';
};
$Array.is$Array = function( a ) {
if ($Array.isArray(a)) { return a.is$Array; }
return false;
};
window.$Array = $Array;
})(window);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment