yui-array.js revision 66abd057e65a9ca9398fbce05417fd1c6a99a5a8
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * The YUI module contains the components required for building the YUI seed
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * file. This includes the script loading mechanism, a simple queue, and the
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * core utilities for the library.
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @module yui
2c5ce90c334a2d0f18474e85c93b424b6ec9daaaAdam Moore * @submodule yui-base
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove * Adds utilities to the YUI instance for working with arrays. Additional array
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * helpers can be found in the `collection` module.
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * @class Array
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove * `Y.Array(thing)` returns an array created from _thing_. Depending on
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove * _thing_'s type, one of the following will happen:
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove * - Arrays are returned unmodified unless a non-zero _startIndex_ is
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove * specified.
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove * - Array-like collections (see `Array.test()`) are converted to arrays.
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove * - For everything else, a new array is created with _thing_ as the sole
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove * Note: elements that are also collections, such as `<form>` and `<select>`
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove * elements, are not automatically converted to arrays. To force a conversion,
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove * pass `true` as the value of the _force_ parameter.
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * @method ()
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove * @param {mixed} thing The thing to arrayify.
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove * @param {int} [startIndex=0] If non-zero and _thing_ is an array or array-like
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove * collection, a subset of items starting at the specified index will be
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove * @param {boolean} [force=false] If `true`, _thing_ will be treated as an
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove * array-like collection no matter what.
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove * @return {Array}
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove // IE throws when trying to slice HTMLElement collections.
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove } catch (ex) {
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove for (len = thing.length; startIndex < len; ++startIndex) {
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove * Evaluates _obj_ to determine if it's an array, an array-like collection, or
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove * something else. This is useful when working with the function `arguments`
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove * collection and `HTMLElement` collections.
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove * Note: This implementation doesn't consider elements that are also
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove * collections, such as `<form>` and `<select>`, to be array-like.
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * @method test
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove * @param {object} obj Object to test.
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove * @return {int} A number indicating the results of the test:
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove * - 0: Neither an array nor an array-like collection.
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove * - 1: Real array.
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove * - 2: Array-like collection.
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove // indexed, but no tagName (element) or alert (window),
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove // or functions without apply/call (Safari
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove // HTMLElementCollection bug).
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove if ('length' in obj && !obj.tagName && !obj.alert && !obj.apply) {
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove } catch (ex) {}
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * Executes the supplied function on each item in the array. This method wraps
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * the native ES5 `Array.forEach()` method if available.
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * @method each
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @param {Array} array Array to iterate.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @param {Function} fn Function to execute on each item in the array.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @param {mixed} fn.item Current array item.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @param {Number} fn.index Current array index.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @param {Array} fn.array Array being iterated.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @param {Object} [thisObj] `this` object to use when calling _fn_.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @return {YUI} The YUI instance.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @chainable
66abd057e65a9ca9398fbce05417fd1c6a99a5a8Ryan GroveYArray.each = YArray.forEach = Native.forEach ? function (array, fn, thisObj) {
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove Native.forEach.call(array || [], fn, thisObj || Y);
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove for (var i = 0, len = (array && array.length) || 0; i < len; ++i) {
66abd057e65a9ca9398fbce05417fd1c6a99a5a8Ryan Grove * Alias for `each`.
66abd057e65a9ca9398fbce05417fd1c6a99a5a8Ryan Grove * @method forEach
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * Returns an object using the first array as keys and the second as values. If
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * the second array is not provided, or if it doesn't contain the same number of
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * values as the first array, then `true` will be used in place of the missing
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * Y.Array.hash(['a', 'b', 'c'], ['foo', 'bar']);
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * // => {a: 'foo', b: 'bar', c: true}
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * @method hash
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @param {Array} keys Array to use as keys.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @param {Array} [values] Array to use as values.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @return {Object}
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove hash[keys[i]] = vlen && vlen > i ? values[i] : true;
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * Returns the index of the first item in the array that's equal (using a strict
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * equality check) to the specified _value_, or `-1` if the value isn't found.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * This method wraps the native ES5 `Array.indexOf()` method if available.
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * @method indexOf
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @param {Array} array Array to search.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @param {any} value Value to search for.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @return {Number} Index of the item strictly equal to _value_, or `-1` if not
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan GroveYArray.indexOf = Native.indexOf ? function (array, value) {
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove // TODO: support fromIndex
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove for (var i = 0, len = array.length; i < len; ++i) {
eb86457f85638a9eb7c4d5f84eb367d24061abfbAdam Moore * Numeric sort convenience function.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * The native `Array.prototype.sort()` function converts values to strings and
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * sorts them in lexicographic order, which is unsuitable for sorting numeric
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * values. Provide `Y.Array.numericSort` as a custom sort function when you want
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * to sort values in numeric order.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * [42, 23, 8, 16, 4, 15].sort(Y.Array.numericSort);
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * // => [4, 8, 15, 16, 23, 42]
eb86457f85638a9eb7c4d5f84eb367d24061abfbAdam Moore * @method numericSort
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @param {Number} a First value to compare.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @param {Number} b Second value to compare.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @return {Number} Difference between _a_ and _b_.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove return a - b;
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * Executes the supplied function on each item in the array. Returning a truthy
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * value from the function will stop the processing of remaining items.
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * @method some
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @param {Array} array Array to iterate.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @param {Function} fn Function to execute on each item.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @param {mixed} fn.value Current array item.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @param {Number} fn.index Current array index.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @param {Array} fn.array Array being iterated.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @param {Object} [thisObj] `this` object to use when calling _fn_.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @return {Boolean} `true` if the function returns a truthy value on any of the
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * items in the array; `false` otherwise.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan GroveYArray.some = Native.some ? function (array, fn, thisObj) {
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove for (var i = 0, len = array.length; i < len; ++i) {
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove return true;
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove return false;