UNPKG

modulex-util

Version:

common utilities from modulex

304 lines (287 loc) 9.94 kB
/** * @ignore * array utilities of lang * @author yiminghe@gmail.com */ var TRUE = true, undef, AP = Array.prototype, indexOf = AP.indexOf, lastIndexOf = AP.lastIndexOf, filter = AP.filter, every = AP.every, some = AP.some, util = require('./base'), map = AP.map, FALSE = false; util.mix(util, { /** * Search for a specified value within an array. * @param item individual item to be searched * @method * @member util * @param {Array} arr the array of items where item will be search * @return {number} item's index in array */ indexOf: indexOf ? function (item, arr, fromIndex) { return fromIndex === undef ? indexOf.call(arr, item) : indexOf.call(arr, item, fromIndex); } : function (item, arr, fromIndex) { for (var i = fromIndex || 0, len = arr.length; i < len; ++i) { if (arr[i] === item) { return i; } } return -1; }, /** * Returns the index of the last item in the array * that contains the specified value, -1 if the * value isn't found. * @method * @param item individual item to be searched * @param {Array} arr the array of items where item will be search * @return {number} item's last index in array * @member util */ lastIndexOf: (lastIndexOf) ? function (item, arr, fromIndex) { return fromIndex === undef ? lastIndexOf.call(arr, item) : lastIndexOf.call(arr, item, fromIndex); } : function (item, arr, fromIndex) { if (fromIndex === undef) { fromIndex = arr.length - 1; } for (var i = fromIndex; i >= 0; i--) { if (arr[i] === item) { break; } } return i; }, /** * Returns a copy of the array with the duplicate entries removed * @param a {Array} the array to find the subset of unique for * @param [override] {Boolean} if override is TRUE, util.unique([a, b, a]) => [b, a]. * if override is FALSE, util.unique([a, b, a]) => [a, b] * @return {Array} a copy of the array with duplicate entries removed * @member util */ unique: function (a, override) { var b = a.slice(); if (override) { b.reverse(); } var i = 0, n, item; while (i < b.length) { item = b[i]; while ((n = util.lastIndexOf(item, b)) !== i) { b.splice(n, 1); } i += 1; } if (override) { b.reverse(); } return b; }, /** * Search for a specified value index within an array. * @param item individual item to be searched * @param {Array} arr the array of items where item will be search * @return {Boolean} the item exists in arr * @member util */ inArray: function (item, arr) { return util.indexOf(item, arr) > -1; }, /** * Executes the supplied function on each item in the array. * Returns a new array containing the items that the supplied * function returned TRUE for. * @member util * @method * @param arr {Array} the array to iterate * @param fn {Function} the function to execute on each item * @param [context] {Object} optional context object * @return {Array} The items on which the supplied function returned TRUE. * If no items matched an empty array is returned. */ filter: filter ? function (arr, fn, context) { return filter.call(arr, fn, context || this); } : function (arr, fn, context) { var ret = []; util.each(arr, function (item, i, arr) { if (fn.call(context || this, item, i, arr)) { ret.push(item); } }); return ret; }, /** * Executes the supplied function on each item in the array. * Returns a new array containing the items that the supplied * function returned for. * @method * @param arr {Array} the array to iterate * @param fn {Function} the function to execute on each item * @param [context] {Object} optional context object * refer: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map * @return {Array} The items on which the supplied function returned * @member util */ map: map ? function (arr, fn, context) { return map.call(arr, fn, context || this); } : function (arr, fn, context) { var len = arr.length, res = new Array(len); for (var i = 0; i < len; i++) { var el = typeof arr === 'string' ? arr.charAt(i) : arr[i]; if (el || //ie<9 in invalid when typeof arr == string i in arr) { res[i] = fn.call(context || this, el, i, arr); } } return res; }, /** * Executes the supplied function on each item in the array. * Returns a value which is accumulation of the value that the supplied * function returned. * * @param arr {Array} the array to iterate * @param callback {Function} the function to execute on each item * @param initialValue {number} optional context object * refer: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/reduce * @return {Array} The items on which the supplied function returned * @member util */ reduce: function (arr, callback, initialValue) { var len = arr.length; if (typeof callback !== 'function') { throw new TypeError('callback is not function!'); } // no value to return if no initial value and an empty array if (len === 0 && arguments.length === 2) { throw new TypeError('arguments invalid'); } var k = 0; var accumulator; if (arguments.length >= 3) { accumulator = initialValue; } else { do { if (k in arr) { accumulator = arr[k++]; break; } // if array contains no values, no initial value to return k += 1; if (k >= len) { throw new TypeError(); } } while (TRUE); } while (k < len) { if (k in arr) { accumulator = callback.call(undef, accumulator, arr[k], k, arr); } k++; } return accumulator; }, /** * Tests whether all elements in the array pass the test implemented by the provided function. * @method * @param arr {Array} the array to iterate * @param callback {Function} the function to execute on each item * @param [context] {Object} optional context object * @member util * @return {Boolean} whether all elements in the array pass the test implemented by the provided function. */ every: every ? function (arr, fn, context) { return every.call(arr, fn, context || this); } : function (arr, fn, context) { var len = arr && arr.length || 0; for (var i = 0; i < len; i++) { if (i in arr && !fn.call(context, arr[i], i, arr)) { return FALSE; } } return TRUE; }, /** * Tests whether some element in the array passes the test implemented by the provided function. * @method * @param arr {Array} the array to iterate * @param callback {Function} the function to execute on each item * @param [context] {Object} optional context object * @member util * @return {Boolean} whether some element in the array passes the test implemented by the provided function. */ some: some ? function (arr, fn, context) { return some.call(arr, fn, context || this); } : function (arr, fn, context) { var len = arr && arr.length || 0; for (var i = 0; i < len; i++) { if (i in arr && fn.call(context, arr[i], i, arr)) { return TRUE; } } return FALSE; }, /** * Converts object to a TRUE array. * do not pass form.elements to this function ie678 bug. * passing arguments is not recommended. * https://github.com/petkaantonov/bluebird/wiki/Optimization-killers * @param o {object|Array} array like object or array * @return {Array} native Array * @member util */ makeArray: function (o) { if (o == null) { return []; } if (util.isArray(o)) { return o; } var lengthType = typeof o.length, oType = typeof o; // The strings and functions also have 'length' if (lengthType !== 'number' || // select element // https://github.com/kissyteam/kissy/issues/537 typeof o.nodeName === 'string' || // window /*jshint eqeqeq:false*/ (o != null && o == o.window) || oType === 'string' || // https://github.com/ariya/phantomjs/issues/11478 (oType === 'function' && !('item' in o && lengthType === 'number'))) { return [o]; } var ret = []; for (var i = 0, l = o.length; i < l; i++) { ret[i] = o[i]; } return ret; } });