Last active
December 23, 2015 13:19
-
-
Save servel333/6641047 to your computer and use it in GitHub Desktop.
A method of extending the Array class without polluting the global namespace.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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