yui-array.js revision 66abd057e65a9ca9398fbce05417fd1c6a99a5a8
4778ff543a041ac356d6e661cc9b66c3fafa2092Adam Moore/**
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
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore */
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grovevar Lang = Y.Lang,
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove Native = Array.prototype;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore/**
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove * Adds utilities to the YUI instance for working with arrays. Additional array
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * helpers can be found in the `collection` module.
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove *
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * @class Array
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore */
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
b39897a381c2203466da5568bfd2862a54a81311Adam Moore/**
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 *
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 * item.
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore *
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.
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore *
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 * returned.
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}
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @static
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore */
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grovefunction YArray(thing, startIndex, force) {
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove var len, result;
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove startIndex || (startIndex = 0);
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove if (force || YArray.test(thing)) {
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove // IE throws when trying to slice HTMLElement collections.
b45133051f787045386e6848ced7996daffd97e5Adam Moore try {
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove return Native.slice.call(thing, startIndex);
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove } catch (ex) {
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove result = [];
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove for (len = thing.length; startIndex < len; ++startIndex) {
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove result.push(thing[startIndex]);
b45133051f787045386e6848ced7996daffd97e5Adam Moore }
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove return result;
b45133051f787045386e6848ced7996daffd97e5Adam Moore }
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore }
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove
10f15e6d01fb5a16131e11a283f2792ac030a83cRyan Grove return [thing];
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove}
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
0263b559dcd210a19a22676b25ecbcac81d1692cAdam MooreY.Array = YArray;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
b39897a381c2203466da5568bfd2862a54a81311Adam Moore/**
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 *
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove * Note: This implementation doesn't consider elements that are also
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove * collections, such as `<form>` and `<select>`, to be array-like.
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore *
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.
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @static
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore */
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan GroveYArray.test = function (obj) {
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove var result = 0;
b39897a381c2203466da5568bfd2862a54a81311Adam Moore
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove if (Lang.isArray(obj)) {
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove result = 1;
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove } else if (Lang.isObject(obj)) {
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove try {
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 result = 2;
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove }
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove } catch (ex) {}
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore }
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove
f5ae9beb0d4988b6817bafde07a3a5bd1cc2731bRyan Grove return result;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore};
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore/**
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.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove *
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
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @static
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore */
66abd057e65a9ca9398fbce05417fd1c6a99a5a8Ryan GroveYArray.each = YArray.forEach = Native.forEach ? function (array, fn, thisObj) {
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove Native.forEach.call(array || [], fn, thisObj || Y);
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove return Y;
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove} : function (array, fn, thisObj) {
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove for (var i = 0, len = (array && array.length) || 0; i < len; ++i) {
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove fn.call(thisObj || Y, array[i], i, array);
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove }
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove return Y;
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove};
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
66abd057e65a9ca9398fbce05417fd1c6a99a5a8Ryan Grove/**
66abd057e65a9ca9398fbce05417fd1c6a99a5a8Ryan Grove * Alias for `each`.
66abd057e65a9ca9398fbce05417fd1c6a99a5a8Ryan Grove *
66abd057e65a9ca9398fbce05417fd1c6a99a5a8Ryan Grove * @method forEach
66abd057e65a9ca9398fbce05417fd1c6a99a5a8Ryan Grove * @static
66abd057e65a9ca9398fbce05417fd1c6a99a5a8Ryan Grove */
66abd057e65a9ca9398fbce05417fd1c6a99a5a8Ryan Grove
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore/**
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 * values.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove *
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @example
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove *
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * Y.Array.hash(['a', 'b', 'c'], ['foo', 'bar']);
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * // => {a: 'foo', b: 'bar', c: true}
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove *
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}
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @static
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore */
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan GroveYArray.hash = function (keys, values) {
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove var hash = {},
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove vlen = values && values.length,
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove i, len;
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove for (i = 0, len = keys.length; i < len; ++i) {
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove hash[keys[i]] = vlen && vlen > i ? values[i] : true;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore }
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove return hash;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore};
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore/**
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 *
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * This method wraps the native ES5 `Array.indexOf()` method if available.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove *
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 Grove * found.
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @static
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore */
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan GroveYArray.indexOf = Native.indexOf ? function (array, value) {
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove // TODO: support fromIndex
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove return Native.indexOf.call(array, value);
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove} : function (array, value) {
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove for (var i = 0, len = array.length; i < len; ++i) {
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove if (array[i] === value) {
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove return i;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore }
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove }
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove return -1;
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove};
a3e6db667fcd33ac653355e76d3660ecf232193bJeff Craig
eb86457f85638a9eb7c4d5f84eb367d24061abfbAdam Moore/**
eb86457f85638a9eb7c4d5f84eb367d24061abfbAdam Moore * Numeric sort convenience function.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove *
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 *
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * @example
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove *
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * [42, 23, 8, 16, 4, 15].sort(Y.Array.numericSort);
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove * // => [4, 8, 15, 16, 23, 42]
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove *
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_.
02b581ebfa9969c32cac8cd44ebe35e0e47f00ceAdam Moore * @static
eb86457f85638a9eb7c4d5f84eb367d24061abfbAdam Moore */
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan GroveYArray.numericSort = function (a, b) {
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove return a - b;
eb86457f85638a9eb7c4d5f84eb367d24061abfbAdam Moore};
eb86457f85638a9eb7c4d5f84eb367d24061abfbAdam Moore
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore/**
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.
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove *
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.
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore * @static
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore */
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan GroveYArray.some = Native.some ? function (array, fn, thisObj) {
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove return Native.some.call(array, fn, thisObj);
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove} : function (array, fn, thisObj) {
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove for (var i = 0, len = array.length; i < len; ++i) {
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove if (fn.call(thisObj, array[i], i, array)) {
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove return true;
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore }
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove }
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove return false;
0a1f30d712713e39834369dc0781ada8459ea5d2Ryan Grove};