yui-array.js revision 0263b559dcd210a19a22676b25ecbcac81d1692c
c4e6d94ea429e473a6732b6eb5e0fc980e822881Adam Moore(function() {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore/**
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * YUI core
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @module yui
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore */
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
ba2701ee03e94104edf19911ee0989f8cee11088Adam Moorevar L = Y.Lang, Native = Array.prototype,
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore/**
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * Adds the following array utilities to the YUI instance
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @class YUI~array
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore */
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore/**
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * Y.Array(o) returns an array:
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * - Arrays are return unmodified unless the start position is specified.
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * - "Array-like" collections (@see Array.test) are converted to arrays
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * - For everything else, a new array is created with the input as the sole item
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * - The start position is used if the input is or is like an array to return
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * a subset of the collection.
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore *
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @TODO this will not automatically convert elements that are also collections
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * such as forms and selects. Passing true as the third param will
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * force a conversion.
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore *
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @method Array
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @static
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @param o the item to arrayify
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @param i {int} if an array or array-like, this is the start index
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @param al {boolean} if true, it forces the array-like fork. This
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * can be used to avoid multiple array.test calls.
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @return {Array} the resulting array
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore */
0263b559dcd210a19a22676b25ecbcac81d1692cAdam MooreYArray = function(o, startIdx, al) {
b45133051f787045386e6848ced7996daffd97e5Adam Moore var t = (al) ? 2 : Y.Array.test(o), i, l, a;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore // switch (t) {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore // case 1:
b45133051f787045386e6848ced7996daffd97e5Adam Moore // // return (startIdx) ? o.slice(startIdx) : o;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore // case 2:
b45133051f787045386e6848ced7996daffd97e5Adam Moore // return Native.slice.call(o, startIdx || 0);
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore // default:
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore // return [o];
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore // }
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore if (t) {
b45133051f787045386e6848ced7996daffd97e5Adam Moore try {
b45133051f787045386e6848ced7996daffd97e5Adam Moore return Native.slice.call(o, startIdx || 0);
b45133051f787045386e6848ced7996daffd97e5Adam Moore // IE errors when trying to slice element collections
b45133051f787045386e6848ced7996daffd97e5Adam Moore } catch(e) {
b45133051f787045386e6848ced7996daffd97e5Adam Moore a=[];
b45133051f787045386e6848ced7996daffd97e5Adam Moore for (i=0, l=o.length; i<l; i=i+1) {
b45133051f787045386e6848ced7996daffd97e5Adam Moore a.push(o[i]);
b45133051f787045386e6848ced7996daffd97e5Adam Moore }
b45133051f787045386e6848ced7996daffd97e5Adam Moore return a;
b45133051f787045386e6848ced7996daffd97e5Adam Moore }
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore } else {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore return [o];
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore }
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore};
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
0263b559dcd210a19a22676b25ecbcac81d1692cAdam MooreY.Array = YArray;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore/**
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * Evaluates the input to determine if it is an array, array-like, or
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * something else. This is used to handle the arguments collection
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * available within functions, and HTMLElement collections
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore *
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @method Array.test
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @static
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore *
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @todo current implementation (intenionally) will not implicitly
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * handle html elements that are array-like (forms, selects, etc).
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore *
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @return {int} a number indicating the results:
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * 0: Not an array or an array-like collection
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * 1: A real array.
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * 2: array-like collection.
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore */
0263b559dcd210a19a22676b25ecbcac81d1692cAdam MooreYArray.test = function(o) {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore var r = 0;
21a04e4a1f3596ab3a9e17fffa80b45eace6b29aAdam Moore if (L.isObject(o)) {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore if (L.isArray(o)) {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore r = 1;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore } else {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore try {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore // indexed, but no tagName (element) or alert (window)
21a04e4a1f3596ab3a9e17fffa80b45eace6b29aAdam Moore if ("length" in o && !("tagName" in o) && !("alert" in o) &&
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore (!Y.Lang.isFunction(o.size) || o.size() > 1)) {
21a04e4a1f3596ab3a9e17fffa80b45eace6b29aAdam Moore r = 2;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore }
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
21a04e4a1f3596ab3a9e17fffa80b45eace6b29aAdam Moore } catch(e) {}
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore }
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore }
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore return r;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore};
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore/**
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * Executes the supplied function on each item in the array.
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @method Array.each
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @param a {Array} the array to iterate
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @param f {Function} the function to execute on each item
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @param o Optional context object
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @static
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @return {YUI} the YUI instance
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore */
0263b559dcd210a19a22676b25ecbcac81d1692cAdam MooreYArray.each = (Native.forEach) ?
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore function (a, f, o) {
401d3c02d890d39b7a48d94e0a9c1830f8aade42Adam Moore Native.forEach.call(a || [], f, o || Y);
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore return Y;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore } :
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore function (a, f, o) {
b1cd8b30205189b0b808fc2c4c93a184a22e24cdAdam Moore var l = (a && a.length) || 0, i;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore for (i = 0; i < l; i=i+1) {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore f.call(o || Y, a[i], i, a);
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore }
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore return Y;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore };
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore/**
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * Returns an object using the first array as keys, and
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * the second as values. If the second array is not
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * provided the value is set to true for each.
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @method Array.hash
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @static
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @param k {Array} keyset
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @param v {Array} optional valueset
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @return {object} the hash
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore */
0263b559dcd210a19a22676b25ecbcac81d1692cAdam MooreYArray.hash = function(k, v) {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore var o = {}, l = k.length, vl = v && v.length, i;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore for (i=0; i<l; i=i+1) {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore o[k[i]] = (vl && vl > i) ? v[i] : true;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore }
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore return o;
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore};
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore/**
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * Returns the index of the first item in the array
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * that contains the specified value, -1 if the
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * value isn't found.
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @method Array.indexOf
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @static
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @param a {Array} the array to search
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @param val the value to search for
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @return {int} the index of the item that contains the value or -1
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore */
0263b559dcd210a19a22676b25ecbcac81d1692cAdam MooreYArray.indexOf = (Native.indexOf) ?
a3e6db667fcd33ac653355e76d3660ecf232193bJeff Craig function(a, val) {
a3e6db667fcd33ac653355e76d3660ecf232193bJeff Craig return a.indexOf(val);
a3e6db667fcd33ac653355e76d3660ecf232193bJeff Craig } :
a3e6db667fcd33ac653355e76d3660ecf232193bJeff Craig function(a, val) {
a3e6db667fcd33ac653355e76d3660ecf232193bJeff Craig for (var i=0; i<a.length; i=i+1) {
a3e6db667fcd33ac653355e76d3660ecf232193bJeff Craig if (a[i] === val) {
a3e6db667fcd33ac653355e76d3660ecf232193bJeff Craig return i;
a3e6db667fcd33ac653355e76d3660ecf232193bJeff Craig }
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore }
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
a3e6db667fcd33ac653355e76d3660ecf232193bJeff Craig return -1;
a3e6db667fcd33ac653355e76d3660ecf232193bJeff Craig };
a3e6db667fcd33ac653355e76d3660ecf232193bJeff Craig
eb86457f85638a9eb7c4d5f84eb367d24061abfbAdam Moore/**
eb86457f85638a9eb7c4d5f84eb367d24061abfbAdam Moore * Numeric sort convenience function.
eb86457f85638a9eb7c4d5f84eb367d24061abfbAdam Moore * Y.ArrayAssert.itemsAreEqual([1, 2, 3], [3, 1, 2].sort(Y.Array.numericSort));
eb86457f85638a9eb7c4d5f84eb367d24061abfbAdam Moore * @method numericSort
eb86457f85638a9eb7c4d5f84eb367d24061abfbAdam Moore */
0263b559dcd210a19a22676b25ecbcac81d1692cAdam MooreYArray.numericSort = function(a, b) {
eb86457f85638a9eb7c4d5f84eb367d24061abfbAdam Moore return (a - b);
eb86457f85638a9eb7c4d5f84eb367d24061abfbAdam Moore};
eb86457f85638a9eb7c4d5f84eb367d24061abfbAdam Moore
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore/**
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore * Executes the supplied function on each item in the array.
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore * Returning true from the processing function will stop the
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore * processing of the remaining
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore * items.
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore * @method Array.some
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore * @param a {Array} the array to iterate
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore * @param f {Function} the function to execute on each item
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore * @param o Optional context object
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore * @static
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore * @return {boolean} true if the function returns true on
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore * any of the items in the array
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore */
0263b559dcd210a19a22676b25ecbcac81d1692cAdam Moore YArray.some = (Native.some) ?
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore function (a, f, o) {
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore return Native.some.call(a, f, o);
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore } :
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore function (a, f, o) {
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore var l = a.length, i;
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore for (i=0; i<l; i=i+1) {
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore if (f.call(o, a[i], i, a)) {
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore return true;
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore }
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore }
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore return false;
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore };
3c245663d1bfadc0536b538247884c0667cc9313Adam Moore
c4e6d94ea429e473a6732b6eb5e0fc980e822881Adam Moore})();