mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-01-31 15:27:50 +00:00
Split _.every, _.filter, _.map, _.reduce, & _.some into arrayXYZ and baseXYZ forms as well as specialize for _.bind and _.partial.
This commit is contained in:
432
lodash.js
432
lodash.js
@@ -1088,6 +1088,28 @@
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* A specialized version of `_.every` for arrays without support for callback
|
||||
* shorthands or `this` binding.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to iterate over.
|
||||
* @param {Function} predicate The function called per iteration.
|
||||
* @returns {Array} Returns `true` if all elements passed the predicate check,
|
||||
* else `false`
|
||||
*/
|
||||
function arrayEvery(array, predicate) {
|
||||
var index = -1,
|
||||
length = array.length;
|
||||
|
||||
while (++index < length) {
|
||||
if (!predicate(array[index], index, array)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* A specialized version of `_.map` for arrays without support for callback
|
||||
* shorthands or `this` binding.
|
||||
@@ -1108,6 +1130,76 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* A specialized version of `_.filter` for arrays without support for callback
|
||||
* shorthands or `this` binding.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to iterate over.
|
||||
* @param {Function} predicate The function called per iteration.
|
||||
* @returns {Array} Returns the new filtered array.
|
||||
*/
|
||||
function arrayFilter(array, predicate) {
|
||||
var index = -1,
|
||||
length = array.length,
|
||||
result = [];
|
||||
|
||||
while (++index < length) {
|
||||
var value = array[index];
|
||||
if (predicate(value, index, array)) {
|
||||
result.push(value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* A specialized version of `_.reduce` for arrays without support for callback
|
||||
* shorthands or `this` binding.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to iterate over.
|
||||
* @param {Function} iterator The function called per iteration.
|
||||
* @param {*} [accumulator] The initial value.
|
||||
* @param {boolean} [initFromArray=false] Specify using the first element of
|
||||
* `array` as the initial value.
|
||||
* @returns {*} Returns the accumulated value.
|
||||
*/
|
||||
function arrayReduce(array, iterator, accumulator, initFromArray) {
|
||||
var index = -1,
|
||||
length = array.length;
|
||||
|
||||
if (initFromArray && length) {
|
||||
accumulator = array[++index];
|
||||
}
|
||||
while (++index < length) {
|
||||
accumulator = iterator(accumulator, array[index], index, array);
|
||||
}
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
/**
|
||||
* A specialized version of `_.some` for arrays without support for callback
|
||||
* shorthands or `this` binding.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to iterate over.
|
||||
* @param {Function} predicate The function called per iteration.
|
||||
* @returns {boolean} Returns `true` if any element passed the predicate check,
|
||||
* else `false`.
|
||||
*/
|
||||
function arraySome(array, predicate) {
|
||||
var index = -1,
|
||||
length = array.length;
|
||||
|
||||
while (++index < length) {
|
||||
if (predicate(array[index], index, array)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by `_.defaults` to customize its `_.assign` use.
|
||||
*
|
||||
@@ -1161,45 +1253,6 @@
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base implementation of `_.bind` which creates the bound function and
|
||||
* sets its metadata.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} data The metadata array.
|
||||
* @returns {Function} Returns the new bound function.
|
||||
*/
|
||||
function baseBind(data) {
|
||||
var func = data[0],
|
||||
thisArg = data[3],
|
||||
partialArgs = data[4],
|
||||
partialHolders = data[6],
|
||||
Ctor = createCtorWrapper(func);
|
||||
|
||||
// `Function#bind` spec
|
||||
// http://es5.github.io/#x15.3.4.5
|
||||
if (partialArgs) {
|
||||
var bound = function() {
|
||||
// avoid `arguments` object use disqualifying optimizations by
|
||||
// converting it to an array before passing it to `composeArgs`
|
||||
var length = arguments.length,
|
||||
args = Array(length);
|
||||
|
||||
while (length--) {
|
||||
args[length] = arguments[length];
|
||||
}
|
||||
args = composeArgs(partialArgs, partialHolders, args);
|
||||
return (this instanceof bound ? Ctor : func).apply(thisArg, args);
|
||||
};
|
||||
} else {
|
||||
bound = function() {
|
||||
return (this instanceof bound ? Ctor : func).apply(thisArg, arguments);
|
||||
};
|
||||
}
|
||||
setData(bound, data);
|
||||
return bound;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base implementation of `_.callback` without support for creating
|
||||
* "_.pluck" and "_.where" style callbacks.
|
||||
@@ -1398,13 +1451,19 @@
|
||||
* @returns {Function} Returns the new function.
|
||||
*/
|
||||
function baseCreateWrapper(data) {
|
||||
var bitmask = data[1];
|
||||
if (bitmask == BIND_FLAG) {
|
||||
return setData(createBindWrapper(data), data);
|
||||
}
|
||||
var partialHolders = data[6];
|
||||
if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !partialHolders.length) {
|
||||
return setData(createPartialWrapper(data), data);
|
||||
}
|
||||
var func = data[0],
|
||||
bitmask = data[1],
|
||||
arity = data[2],
|
||||
thisArg = data[3],
|
||||
partialArgs = data[4],
|
||||
partialRightArgs = data[5],
|
||||
partialHolders = data[6],
|
||||
partialRightHolders = data[7];
|
||||
|
||||
var isBind = bitmask & BIND_FLAG,
|
||||
@@ -1416,7 +1475,7 @@
|
||||
var Ctor = !isBindKey && createCtorWrapper(func),
|
||||
key = func;
|
||||
|
||||
function bound() {
|
||||
var wrapper = function() {
|
||||
var length = arguments.length,
|
||||
index = length,
|
||||
args = Array(length);
|
||||
@@ -1451,10 +1510,10 @@
|
||||
if (isBindKey) {
|
||||
func = thisBinding[key];
|
||||
}
|
||||
return (this instanceof bound ? (Ctor || createCtorWrapper(func)) : func).apply(thisBinding, args);
|
||||
}
|
||||
setData(bound, data);
|
||||
return bound;
|
||||
return (this instanceof wrapper ? (Ctor || createCtorWrapper(func)) : func).apply(thisBinding, args);
|
||||
};
|
||||
|
||||
return setData(wrapper, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1577,6 +1636,46 @@
|
||||
return collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base implementation of `_.every` without support for callback shorthands
|
||||
* or `this` binding.
|
||||
*
|
||||
* @private
|
||||
* @param {Array|Object|string} collection The collection to iterate over.
|
||||
* @param {Function} predicate The function called per iteration.
|
||||
* @returns {Array} Returns `true` if all elements passed the predicate check,
|
||||
* else `false`
|
||||
*/
|
||||
function baseEvery(collection, predicate) {
|
||||
var result = true;
|
||||
|
||||
baseEach(collection, function(value, index, collection) {
|
||||
result = !!predicate(value, index, collection);
|
||||
return result;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base implementation of `_.filter` without support for callback shorthands
|
||||
* or `this` binding.
|
||||
*
|
||||
* @private
|
||||
* @param {Array|Object|string} collection The collection to iterate over.
|
||||
* @param {Function} predicate The function called per iteration.
|
||||
* @returns {Array} Returns the new filtered array.
|
||||
*/
|
||||
function baseFilter(collection, predicate) {
|
||||
var result = [];
|
||||
|
||||
baseEach(collection, function(value, index, collection) {
|
||||
if (predicate(value, index, collection)) {
|
||||
result.push(value);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`,
|
||||
* without support for callback shorthands and `this` binding, which iterates
|
||||
@@ -1973,6 +2072,24 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base implementation of `_.map` without support for callback shorthands
|
||||
* or `this` binding.
|
||||
*
|
||||
* @private
|
||||
* @param {Array|Object|string} collection The collection to iterate over.
|
||||
* @param {Function} iterator The function called per iteration.
|
||||
* @returns {Array} Returns the new mapped array.
|
||||
*/
|
||||
function baseMap(collection, iterator) {
|
||||
var result = [];
|
||||
|
||||
baseEach(collection, function(value, key, collection) {
|
||||
result.push(iterator(value, key, collection));
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base implementation of `_.merge` without support for argument juggling,
|
||||
* multiple sources, and `this` binding.
|
||||
@@ -2128,6 +2245,47 @@
|
||||
return min + floor(nativeRandom() * (max - min + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* The base implementation of `_.reduce` without support for callback
|
||||
* shorthands or `this` binding.
|
||||
*
|
||||
* @private
|
||||
* @param {Array|Object|string} collection The collection to iterate over.
|
||||
* @param {Function} iterator The function called per iteration.
|
||||
* @param {*} [accumulator] The initial value.
|
||||
* @param {boolean} [initFromCollection=false] Specify using the first element
|
||||
* of `collection` as the initial value.
|
||||
* @returns {*} Returns the accumulated value.
|
||||
*/
|
||||
function baseReduce(collection, iterator, accumulator, initFromCollection) {
|
||||
baseEach(collection, function(value, index, collection) {
|
||||
accumulator = initFromCollection
|
||||
? (initFromCollection = false, value)
|
||||
: iterator(accumulator, value, index, collection)
|
||||
});
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base implementation of `_.some` without support for callback shorthands
|
||||
* or `this` binding.
|
||||
*
|
||||
* @private
|
||||
* @param {Array|Object|string} collection The collection to iterate over.
|
||||
* @param {Function} predicate The function called per iteration.
|
||||
* @returns {boolean} Returns `true` if any element passed the predicate check,
|
||||
* else `false`.
|
||||
*/
|
||||
function baseSome(collection, predicate) {
|
||||
var result;
|
||||
|
||||
baseEach(collection, function(value, index, collection) {
|
||||
result = predicate(value, index, collection);
|
||||
return !result;
|
||||
});
|
||||
return !!result;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base implementation of `_.uniq` without support for callback shorthands
|
||||
* and `this` binding.
|
||||
@@ -2368,6 +2526,25 @@
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a function that invokes the function specified in the metadata
|
||||
* with its associated `this` binding.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} data The metadata array.
|
||||
* @returns {Function} Returns the new bound function.
|
||||
*/
|
||||
function createBindWrapper(data) {
|
||||
var func = data[0],
|
||||
thisArg = data[3],
|
||||
Ctor = createCtorWrapper(func);
|
||||
|
||||
function wrapper() {
|
||||
return (this instanceof wrapper ? Ctor : func).apply(thisArg, arguments);
|
||||
}
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a cache object to optimize linear searches of large arrays.
|
||||
*
|
||||
@@ -2428,6 +2605,45 @@
|
||||
return repeat(chars, ceil(padLength / chars.length)).slice(0, padLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a function that invokes the function specified in the metadata
|
||||
* with its associated partially applied arguments and optional `this` binding.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} data The metadata array.
|
||||
* @returns {Function} Returns the new bound function.
|
||||
*/
|
||||
function createPartialWrapper(data) {
|
||||
var func = data[0],
|
||||
bitmask = data[1],
|
||||
thisArg = data[3],
|
||||
partialArgs = data[4],
|
||||
partialHolders = data[6];
|
||||
|
||||
var isBind = bitmask & BIND_FLAG,
|
||||
Ctor = createCtorWrapper(func);
|
||||
|
||||
function wrapper() {
|
||||
// avoid `arguments` object use disqualifying optimizations by
|
||||
// converting it to an array before passing it to `composeArgs`
|
||||
var argsIndex = 0,
|
||||
argsLength = arguments.length,
|
||||
leftIndex = -1,
|
||||
leftLength = partialArgs.length,
|
||||
args = Array(argsLength + leftLength),
|
||||
thisBinding = isBind ? thisArg : this;
|
||||
|
||||
while (++leftIndex < leftLength) {
|
||||
args[leftIndex] = partialArgs[leftIndex];
|
||||
}
|
||||
while (argsLength--) {
|
||||
args[leftIndex++] = arguments[argsIndex++];
|
||||
}
|
||||
return (this instanceof wrapper ? Ctor : func).apply(thisBinding, args);
|
||||
}
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a function that either curries or invokes `func` with an optional
|
||||
* `this` binding and partially applied arguments.
|
||||
@@ -2524,12 +2740,7 @@
|
||||
arity = isBindKey ? 0 : func.length;
|
||||
}
|
||||
arity = nativeMax(arity, 0);
|
||||
|
||||
// fast path for `_.bind`
|
||||
data = [func, bitmask, arity, thisArg, partialArgs, partialRightArgs, partialHolders, partialRightHolders];
|
||||
return (bitmask == BIND_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG))
|
||||
? baseBind(data)
|
||||
: baseCreateWrapper(data);
|
||||
return baseCreateWrapper([func, bitmask, arity, thisArg, partialArgs, partialRightArgs, partialHolders, partialRightHolders]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2627,11 +2838,13 @@
|
||||
* @private
|
||||
* @param {Function} func The function to set data on.
|
||||
* @param {Array} value The data array to set.
|
||||
* @returns {Function} Returns `func`.
|
||||
*/
|
||||
var setData = !defineProperty ? noop : function(func, value) {
|
||||
var setData = !defineProperty ? identity : function(func, value) {
|
||||
descriptor.value = value;
|
||||
defineProperty(func, expando, descriptor);
|
||||
descriptor.value = null;
|
||||
return func;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -4157,27 +4370,11 @@
|
||||
* // => false
|
||||
*/
|
||||
function every(collection, predicate, thisArg) {
|
||||
var result = true;
|
||||
|
||||
if (typeof predicate != 'function' || typeof thisArg != 'undefined') {
|
||||
predicate = lodash.callback(predicate, thisArg, 3);
|
||||
}
|
||||
if (isArray(collection)) {
|
||||
var index = -1,
|
||||
length = collection.length;
|
||||
|
||||
while (++index < length) {
|
||||
if (!predicate(collection[index], index, collection)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
baseEach(collection, function(value, index, collection) {
|
||||
result = !!predicate(value, index, collection);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
return result;
|
||||
var func = isArray(collection) ? arrayEvery : baseEvery;
|
||||
return func(collection, predicate);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4221,27 +4418,10 @@
|
||||
* // => [{ 'name': 'barney', 'age': 36 }]
|
||||
*/
|
||||
function filter(collection, predicate, thisArg) {
|
||||
var result = [];
|
||||
predicate = lodash.callback(predicate, thisArg, 3);
|
||||
|
||||
if (isArray(collection)) {
|
||||
var index = -1,
|
||||
length = collection.length;
|
||||
|
||||
while (++index < length) {
|
||||
var value = collection[index];
|
||||
if (predicate(value, index, collection)) {
|
||||
result.push(value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
baseEach(collection, function(value, index, collection) {
|
||||
if (predicate(value, index, collection)) {
|
||||
result.push(value);
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
var func = isArray(collection) ? arrayFilter : baseFilter;
|
||||
return func(collection, predicate);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4556,16 +4736,8 @@
|
||||
function map(collection, iterator, thisArg) {
|
||||
iterator = lodash.callback(iterator, thisArg, 3);
|
||||
|
||||
if (isArray(collection)) {
|
||||
return arrayMap(collection, iterator, thisArg);
|
||||
}
|
||||
var index = -1,
|
||||
result = [];
|
||||
|
||||
baseEach(collection, function(value, key, collection) {
|
||||
result[++index] = iterator(value, key, collection);
|
||||
});
|
||||
return result;
|
||||
var func = isArray(collection) ? arrayMap : baseMap;
|
||||
return func(collection, iterator);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4800,8 +4972,8 @@
|
||||
* each element in the collection through `iterator`, where each successive
|
||||
* execution consumes the return value of the previous execution. If `accumulator`
|
||||
* is not provided the first element of the collection is used as the initial
|
||||
* `accumulator` value. The `iterator` is bound to `thisArg`and invoked with
|
||||
* four arguments; (accumulator, value, index|key, collection).
|
||||
* value. The `iterator` is bound to `thisArg`and invoked with four arguments;
|
||||
* (accumulator, value, index|key, collection).
|
||||
*
|
||||
* @static
|
||||
* @memberOf _
|
||||
@@ -4809,7 +4981,7 @@
|
||||
* @category Collection
|
||||
* @param {Array|Object|string} collection The collection to iterate over.
|
||||
* @param {Function} [iterator=identity] The function called per iteration.
|
||||
* @param {*} [accumulator] Initial value of the accumulator.
|
||||
* @param {*} [accumulator] The initial value.
|
||||
* @param {*} [thisArg] The `this` binding of `iterator`.
|
||||
* @returns {*} Returns the accumulated value.
|
||||
* @example
|
||||
@@ -4824,27 +4996,10 @@
|
||||
* // => { 'a': 3, 'b': 6, 'c': 9 }
|
||||
*/
|
||||
function reduce(collection, iterator, accumulator, thisArg) {
|
||||
var noaccum = arguments.length < 3;
|
||||
iterator = lodash.callback(iterator, thisArg, 4);
|
||||
|
||||
if (isArray(collection)) {
|
||||
var index = -1,
|
||||
length = collection.length;
|
||||
|
||||
if (noaccum && length) {
|
||||
accumulator = collection[++index];
|
||||
}
|
||||
while (++index < length) {
|
||||
accumulator = iterator(accumulator, collection[index], index, collection);
|
||||
}
|
||||
} else {
|
||||
baseEach(collection, function(value, index, collection) {
|
||||
accumulator = noaccum
|
||||
? (noaccum = false, value)
|
||||
: iterator(accumulator, value, index, collection)
|
||||
});
|
||||
}
|
||||
return accumulator;
|
||||
var func = isArray(collection) ? arrayReduce : baseReduce;
|
||||
return func(collection, iterator, accumulator, arguments.length < 3);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4857,7 +5012,7 @@
|
||||
* @category Collection
|
||||
* @param {Array|Object|string} collection The collection to iterate over.
|
||||
* @param {Function} [iterator=identity] The function called per iteration.
|
||||
* @param {*} [accumulator] Initial value of the accumulator.
|
||||
* @param {*} [accumulator] The initial value.
|
||||
* @param {*} [thisArg] The `this` binding of `iterator`.
|
||||
* @returns {*} Returns the accumulated value.
|
||||
* @example
|
||||
@@ -4940,13 +5095,15 @@
|
||||
* // => [3, 1]
|
||||
*/
|
||||
function sample(collection, n, guard) {
|
||||
if (collection && typeof collection.length != 'number') {
|
||||
var length = collection ? collection.length : 0;
|
||||
|
||||
if (!(typeof length == 'number' && length > -1 && length <= maxSafeInteger)) {
|
||||
collection = values(collection);
|
||||
length = collection.length;
|
||||
} else if (support.unindexedChars && isString(collection)) {
|
||||
collection = collection.split('');
|
||||
}
|
||||
if (n == null || guard) {
|
||||
var length = collection ? collection.length : 0;
|
||||
return length > 0 ? collection[baseRandom(0, length - 1)] : undefined;
|
||||
}
|
||||
var result = shuffle(collection);
|
||||
@@ -5052,27 +5209,11 @@
|
||||
* // => false
|
||||
*/
|
||||
function some(collection, predicate, thisArg) {
|
||||
var result;
|
||||
|
||||
if (typeof predicate != 'function' || typeof thisArg != 'undefined') {
|
||||
predicate = lodash.callback(predicate, thisArg, 3);
|
||||
}
|
||||
if (isArray(collection)) {
|
||||
var index = -1,
|
||||
length = collection.length;
|
||||
|
||||
while (++index < length) {
|
||||
if (predicate(collection[index], index, collection)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
baseEach(collection, function(value, index, collection) {
|
||||
result = predicate(value, index, collection);
|
||||
return !result;
|
||||
});
|
||||
}
|
||||
return !!result;
|
||||
var func = isArray(collection) ? arraySome : baseSome;
|
||||
return func(collection, predicate);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5169,7 +5310,8 @@
|
||||
* // => [2, 3, 4]
|
||||
*/
|
||||
function toArray(collection) {
|
||||
var length = collection && collection.length;
|
||||
var length = collection ? collection.length : 0;
|
||||
|
||||
if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) {
|
||||
return (support.unindexedChars && isString(collection))
|
||||
? collection.split('')
|
||||
@@ -6620,7 +6762,7 @@
|
||||
return result;
|
||||
}
|
||||
var length = value.length;
|
||||
if ((length > -1 && length <= maxSafeInteger) &&
|
||||
if ((typeof length == 'number' && length > -1 && length <= maxSafeInteger) &&
|
||||
(isArray(value) || isString(value) || isArguments(value) ||
|
||||
(typeof value == 'object' && isFunction(value.splice)))) {
|
||||
return !length;
|
||||
|
||||
Reference in New Issue
Block a user