array-extras.js revision cc993d3cace28dec43cfc6f55b41961e90e76ba9
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore/**
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan GroveAdds additional utility methods to the `Y.Array` class.
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@module collection
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@submodule array-extras
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove**/
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grovevar L = Y.Lang, Native = Array.prototype, A = Y.Array;
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore/**
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan GroveReturns the index of the last item in the array that contains the specified
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grovevalue, or `-1` if the value isn't found.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@method lastIndexOf
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Array} a Array to search in.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Any} val Value to search for.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Number} [fromIndex] Index at which to start searching backwards.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove Defaults to the array's length - 1. If negative, it will be taken as an offset
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove from the end of the array. If the calculated index is less than 0, the array
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove will not be searched and `-1` will be returned.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@return {Number} Index of the item that contains the value, or `-1` if not
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove found.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@static
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@for Array
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove**/
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan GroveA.lastIndexOf = Native.lastIndexOf ?
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan Grove function(a, val, fromIndex) {
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan Grove // An undefined fromIndex is still considered a value by some (all?)
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan Grove // native implementations, so we can't pass it unless it's actually
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan Grove // specified.
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan Grove return fromIndex || fromIndex === 0 ? a.lastIndexOf(val, fromIndex) :
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan Grove a.lastIndexOf(val);
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore } :
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan Grove function(a, val, fromIndex) {
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan Grove var len = a.length,
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan Grove i = len - 1;
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan Grove
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan Grove if (fromIndex || fromIndex === 0) {
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan Grove i = Math.min(fromIndex < 0 ? len + fromIndex : fromIndex, len);
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan Grove }
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan Grove
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan Grove if (i > -1 && len > 0) {
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan Grove for (; i > -1; --i) {
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan Grove if (a[i] === val) {
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan Grove return i;
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan Grove }
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore }
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore }
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan Grove
b1715f7fb8a67be6502d58d4dc5a00918f01fa16Ryan Grove return -1;
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore };
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore/**
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan GroveReturns a copy of the specified array with duplicate items removed.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@method unique
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Array} a Array to dedupe.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@return {Array} Copy of the array with duplicate items removed.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@static
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove**/
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam MooreA.unique = function(a, sort) {
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove // Note: the sort param is deprecated and intentionally undocumented since
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove // YUI 3.3.0. It never did what the API docs said it did (see the older
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove // comment below as well).
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove var i = 0,
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove len = a.length,
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove results = [],
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove item, j;
0dd2ce2702cb49626c42d19bff27c7b58738dc05Adam Moore
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove for (; i < len; ++i) {
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove item = a[i];
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove // This loop iterates over the results array in reverse order and stops
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove // if it finds an item that matches the current input array item (a
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove // dupe). If it makes it all the way through without finding a dupe, the
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove // current item is pushed onto the results array.
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove for (j = results.length; j > -1; --j) {
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove if (item === results[j]) {
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove break;
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove }
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove }
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove if (j === -1) {
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove results.push(item);
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore }
0dd2ce2702cb49626c42d19bff27c7b58738dc05Adam Moore }
0dd2ce2702cb49626c42d19bff27c7b58738dc05Adam Moore
0dd2ce2702cb49626c42d19bff27c7b58738dc05Adam Moore // Note: the sort option doesn't really belong here... I think it was added
0dd2ce2702cb49626c42d19bff27c7b58738dc05Adam Moore // because there was a way to fast path the two operations together. That
0dd2ce2702cb49626c42d19bff27c7b58738dc05Adam Moore // implementation was not working, so I replaced it with the following.
0dd2ce2702cb49626c42d19bff27c7b58738dc05Adam Moore // Leaving it in so that the API doesn't get broken.
0dd2ce2702cb49626c42d19bff27c7b58738dc05Adam Moore if (sort) {
a05b931c6d7db4a5df53cfd1d2d505cb07859e66Ryan Grove Y.log('The sort parameter is deprecated and will be removed in a future version of YUI.', 'warn', 'deprecated');
a05b931c6d7db4a5df53cfd1d2d505cb07859e66Ryan Grove
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove if (L.isNumber(results[0])) {
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove results.sort(A.numericSort);
0dd2ce2702cb49626c42d19bff27c7b58738dc05Adam Moore } else {
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove results.sort();
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore }
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore }
0dd2ce2702cb49626c42d19bff27c7b58738dc05Adam Moore
07ed44f0197e6e672f8d8af4b787d895ca237180Ryan Grove return results;
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore};
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore/**
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan GroveExecutes the supplied function on each item in the array. Returns a new array
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grovecontaining the items for which the supplied function returned a truthy value.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@method filter
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Array} a Array to filter.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Function} f Function to execute on each item.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Object} [o] Optional context object.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@return {Array} Array of items for which the supplied function returned a
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove truthy value (empty if it never returned a truthy value).
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@static
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore*/
d4e1418016231206366a3c7d9945be93696db05fRyan GroveA.filter = Native.filter ?
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore function(a, f, o) {
d4e1418016231206366a3c7d9945be93696db05fRyan Grove return a.filter(f, o);
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore } :
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore function(a, f, o) {
d4e1418016231206366a3c7d9945be93696db05fRyan Grove var i = 0,
d4e1418016231206366a3c7d9945be93696db05fRyan Grove len = a.length,
d4e1418016231206366a3c7d9945be93696db05fRyan Grove results = [],
d4e1418016231206366a3c7d9945be93696db05fRyan Grove item;
d4e1418016231206366a3c7d9945be93696db05fRyan Grove
d4e1418016231206366a3c7d9945be93696db05fRyan Grove for (; i < len; ++i) {
701eda2eb4521a1f3fb46f0d6aa587433a9ccbb7Ryan Grove if (i in a) {
701eda2eb4521a1f3fb46f0d6aa587433a9ccbb7Ryan Grove item = a[i];
d4e1418016231206366a3c7d9945be93696db05fRyan Grove
701eda2eb4521a1f3fb46f0d6aa587433a9ccbb7Ryan Grove if (f.call(o, item, i, a)) {
701eda2eb4521a1f3fb46f0d6aa587433a9ccbb7Ryan Grove results.push(item);
701eda2eb4521a1f3fb46f0d6aa587433a9ccbb7Ryan Grove }
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore }
d4e1418016231206366a3c7d9945be93696db05fRyan Grove }
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore return results;
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore };
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore/**
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan GroveThe inverse of `Array.filter()`. Executes the supplied function on each item.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan GroveReturns a new array containing the items for which the supplied function
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grovereturned `false`.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@method reject
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Array} a the array to iterate.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Function} f the function to execute on each item.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {object} [o] Optional context object.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@return {Array} The items for which the supplied function returned `false`.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@static
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore*/
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam MooreA.reject = function(a, f, o) {
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore return A.filter(a, function(item, i, a) {
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore return !f.call(o, item, i, a);
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore });
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore};
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore/**
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan GroveExecutes the supplied function on each item in the array. Iteration stops if the
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grovesupplied function does not return a truthy value.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@method every
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Array} a the array to iterate.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Function} f the function to execute on each item.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Object} [o] Optional context object.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@return {Boolean} `true` if every item in the array returns `true` from the
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove supplied function, `false` otherwise.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@static
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore*/
4c6883fc6c94ac75099a9876dcc79becac62beafRyan GroveA.every = Native.every ?
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore function(a, f, o) {
4c6883fc6c94ac75099a9876dcc79becac62beafRyan Grove return a.every(f, o);
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore } :
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore function(a, f, o) {
4c6883fc6c94ac75099a9876dcc79becac62beafRyan Grove for (var i = 0, l = a.length; i < l; ++i) {
701eda2eb4521a1f3fb46f0d6aa587433a9ccbb7Ryan Grove if (i in a && !f.call(o, a[i], i, a)) {
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore return false;
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore }
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore }
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore return true;
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore };
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore/**
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan GroveExecutes the supplied function on each item in the array and returns a new array
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grovecontaining all the values returned by the supplied function.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@example
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove // Convert an array of numbers into an array of strings.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove Y.Array.map([1, 2, 3, 4], function (item) {
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove return '' + item;
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove });
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove // => ['1', '2', '3', '4']
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@method map
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Array} a the array to iterate.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Function} f the function to execute on each item.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {object} [o] Optional context object.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@return {Array} A new array containing the return value of the supplied function
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove for each item in the original array.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@static
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore*/
847451b874697fc7df2c96af3935bcdc4c32f105Ryan GroveA.map = Native.map ?
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore function(a, f, o) {
847451b874697fc7df2c96af3935bcdc4c32f105Ryan Grove return a.map(f, o);
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore } :
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore function(a, f, o) {
847451b874697fc7df2c96af3935bcdc4c32f105Ryan Grove var i = 0,
847451b874697fc7df2c96af3935bcdc4c32f105Ryan Grove len = a.length,
847451b874697fc7df2c96af3935bcdc4c32f105Ryan Grove results = a.concat();
847451b874697fc7df2c96af3935bcdc4c32f105Ryan Grove
847451b874697fc7df2c96af3935bcdc4c32f105Ryan Grove for (; i < len; ++i) {
701eda2eb4521a1f3fb46f0d6aa587433a9ccbb7Ryan Grove if (i in a) {
701eda2eb4521a1f3fb46f0d6aa587433a9ccbb7Ryan Grove results[i] = f.call(o, a[i], i, a);
701eda2eb4521a1f3fb46f0d6aa587433a9ccbb7Ryan Grove }
847451b874697fc7df2c96af3935bcdc4c32f105Ryan Grove }
847451b874697fc7df2c96af3935bcdc4c32f105Ryan Grove
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore return results;
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore };
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore/**
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan GroveExecutes the supplied function on each item in the array, "folding" the array
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Groveinto a single value.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@method reduce
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Array} a Array to iterate.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Any} init Initial value to start with.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Function} f Function to execute on each item. This function should
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove update and return the value of the computation. It will receive the following
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove arguments:
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove @param {Any} f.previousValue Value returned from the previous iteration,
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove or the initial value if this is the first iteration.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove @param {Any} f.currentValue Value of the current item being iterated.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove @param {Number} f.index Index of the current item.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove @param {Array} f.array Array being iterated.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Object} [o] Optional context object.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@return {Any} Final result from iteratively applying the given function to each
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove element in the array.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@static
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore*/
259d423ddcd9feed2ca363af9e28bf8df4b0d832Ryan GroveA.reduce = Native.reduce ?
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore function(a, init, f, o) {
259d423ddcd9feed2ca363af9e28bf8df4b0d832Ryan Grove // ES5 Array.reduce doesn't support a thisObject, so we need to
259d423ddcd9feed2ca363af9e28bf8df4b0d832Ryan Grove // implement it manually
259d423ddcd9feed2ca363af9e28bf8df4b0d832Ryan Grove return a.reduce(function(init, item, i, a) {
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore return f.call(o, init, item, i, a);
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore }, init);
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore } :
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore function(a, init, f, o) {
259d423ddcd9feed2ca363af9e28bf8df4b0d832Ryan Grove var i = 0,
259d423ddcd9feed2ca363af9e28bf8df4b0d832Ryan Grove len = a.length,
259d423ddcd9feed2ca363af9e28bf8df4b0d832Ryan Grove result = init;
259d423ddcd9feed2ca363af9e28bf8df4b0d832Ryan Grove
259d423ddcd9feed2ca363af9e28bf8df4b0d832Ryan Grove for (; i < len; ++i) {
701eda2eb4521a1f3fb46f0d6aa587433a9ccbb7Ryan Grove if (i in a) {
701eda2eb4521a1f3fb46f0d6aa587433a9ccbb7Ryan Grove result = f.call(o, result, a[i], i, a);
701eda2eb4521a1f3fb46f0d6aa587433a9ccbb7Ryan Grove }
259d423ddcd9feed2ca363af9e28bf8df4b0d832Ryan Grove }
259d423ddcd9feed2ca363af9e28bf8df4b0d832Ryan Grove
259d423ddcd9feed2ca363af9e28bf8df4b0d832Ryan Grove return result;
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore };
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore/**
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan GroveExecutes the supplied function on each item in the array, searching for the
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grovefirst item that matches the supplied function.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@method find
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Array} a the array to search.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Function} f the function to execute on each item. Iteration is stopped
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove as soon as this function returns `true`.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Object} [o] Optional context object.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@return {Object} the first item that the supplied function returns `true` for,
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove or `null` if it never returns `true`.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@static
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore*/
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam MooreA.find = function(a, f, o) {
a0e486c33f9e4fae413b80adc659a906586f1ed3Adam Moore for (var i = 0, l = a.length; i < l; i++) {
701eda2eb4521a1f3fb46f0d6aa587433a9ccbb7Ryan Grove if (i in a && f.call(o, a[i], i, a)) {
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore return a[i];
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore }
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore }
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore return null;
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore};
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore/**
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan GroveIterates over an array, returning a new array of all the elements that match the
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grovesupplied regular expression.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@method grep
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Array} a Array to iterate over.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {RegExp} pattern Regular expression to test against each item.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@return {Array} All the items in the array that produce a match against the
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove supplied regular expression. If no items match, an empty array is returned.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@static
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore*/
a0e486c33f9e4fae413b80adc659a906586f1ed3Adam MooreA.grep = function(a, pattern) {
a0e486c33f9e4fae413b80adc659a906586f1ed3Adam Moore return A.filter(a, function(item, index) {
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore return pattern.test(item);
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore });
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore};
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore/**
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan GrovePartitions an array into two new arrays, one with the items for which the
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grovesupplied function returns `true`, and one with the items for which the function
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grovereturns `false`.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@method partition
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Array} a Array to iterate over.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Function} f Function to execute for each item in the array. It will
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove receive the following arguments:
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove @param {Any} f.item Current item.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove @param {Number} f.index Index of the current item.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove @param {Array} f.array The array being iterated.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Object} [o] Optional execution context.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@return {Object} An object with two properties: `matches` and `rejects`. Each is
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove an array containing the items that were selected or rejected by the test
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove function (or an empty array if none).
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@static
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore*/
a0e486c33f9e4fae413b80adc659a906586f1ed3Adam MooreA.partition = function(a, f, o) {
77233109ecd5f5823f64aed88ebfbae24c2d402fAdam Moore var results = {
a0e486c33f9e4fae413b80adc659a906586f1ed3Adam Moore matches: [],
77233109ecd5f5823f64aed88ebfbae24c2d402fAdam Moore rejects: []
77233109ecd5f5823f64aed88ebfbae24c2d402fAdam Moore };
77233109ecd5f5823f64aed88ebfbae24c2d402fAdam Moore
a0e486c33f9e4fae413b80adc659a906586f1ed3Adam Moore A.each(a, function(item, index) {
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore var set = f.call(o, item, index, a) ? results.matches : results.rejects;
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore set.push(item);
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore });
77233109ecd5f5823f64aed88ebfbae24c2d402fAdam Moore
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore return results;
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore};
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore/**
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan GroveCreates an array of arrays by pairing the corresponding elements of two arrays
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grovetogether into a new array.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@method zip
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Array} a Array to iterate over.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@param {Array} a2 Another array whose values will be paired with values of the
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove first array.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@return {Array} An array of arrays formed by pairing each element of the first
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove array with an item in the second array having the corresponding index.
cc993d3cace28dec43cfc6f55b41961e90e76ba9Ryan Grove@static
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore*/
a0e486c33f9e4fae413b80adc659a906586f1ed3Adam MooreA.zip = function(a, a2) {
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore var results = [];
a0e486c33f9e4fae413b80adc659a906586f1ed3Adam Moore A.each(a, function(item, index) {
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore results.push([item, a2[index]]);
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore });
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore return results;
bb9912c86249bf7dec59ddc9d28434cabba9309aAdam Moore};