mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-08 02:17:48 +00:00
Add toIterable to reduce support.unindexedChars use and optimize/simplify methods. [closes #601]
This commit is contained in:
154
lodash.js
154
lodash.js
@@ -630,7 +630,7 @@
|
|||||||
var fnToString = Function.prototype.toString;
|
var fnToString = Function.prototype.toString;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used as the maximum length of an array-like object.
|
* Used as the maximum length of an array-like value.
|
||||||
* See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength)
|
* See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength)
|
||||||
* for more details.
|
* for more details.
|
||||||
*/
|
*/
|
||||||
@@ -757,8 +757,9 @@
|
|||||||
* `isString`, `isUndefined`, `join`, `kebabCase`, `last`, `lastIndexOf`,
|
* `isString`, `isUndefined`, `join`, `kebabCase`, `last`, `lastIndexOf`,
|
||||||
* `max`, `min`, `noConflict`, `now`, `pad`, `padLeft`, `padRight`, `parseInt`,
|
* `max`, `min`, `noConflict`, `now`, `pad`, `padLeft`, `padRight`, `parseInt`,
|
||||||
* `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, `runInContext`,
|
* `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, `runInContext`,
|
||||||
* `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, `startsWith`, `template`,
|
* `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`,
|
||||||
* `trim`, `trimLeft`, `trimRight`, `trunc`, `unescape`, `uniqueId`, and `value`
|
* `startsWith`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`,
|
||||||
|
* `unescape`, `uniqueId`, and `value`
|
||||||
*
|
*
|
||||||
* The wrapper function `sample` will return a wrapped value when `n` is
|
* The wrapper function `sample` will return a wrapped value when `n` is
|
||||||
* provided, otherwise it will return an unwrapped value.
|
* provided, otherwise it will return an unwrapped value.
|
||||||
@@ -1226,7 +1227,7 @@
|
|||||||
* @returns {*} Returns the value to assign to the destination object.
|
* @returns {*} Returns the value to assign to the destination object.
|
||||||
*/
|
*/
|
||||||
function assignOwnDefaults(objectValue, sourceValue, key, object) {
|
function assignOwnDefaults(objectValue, sourceValue, key, object) {
|
||||||
return (!hasOwnProperty.call(object, key) || typeof objectValue == 'undefined')
|
return (typeof objectValue == 'undefined' || !hasOwnProperty.call(object, key))
|
||||||
? sourceValue
|
? sourceValue
|
||||||
: objectValue
|
: objectValue
|
||||||
}
|
}
|
||||||
@@ -1589,21 +1590,17 @@
|
|||||||
* @returns {Array|Object|string} Returns `collection`.
|
* @returns {Array|Object|string} Returns `collection`.
|
||||||
*/
|
*/
|
||||||
function baseEach(collection, iterator) {
|
function baseEach(collection, iterator) {
|
||||||
|
var length = collection ? collection.length : 0;
|
||||||
|
if (!(typeof length == 'number' && length > -1 && length <= maxSafeInteger)) {
|
||||||
|
return baseForOwn(collection, iterator);
|
||||||
|
}
|
||||||
var index = -1,
|
var index = -1,
|
||||||
iterable = collection,
|
iterable = toIterable(collection);
|
||||||
length = collection ? collection.length : 0;
|
|
||||||
|
|
||||||
if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) {
|
while (++index < length) {
|
||||||
if (support.unindexedChars && isString(iterable)) {
|
if (iterator(iterable[index], index, collection) === false) {
|
||||||
iterable = iterable.split('');
|
break;
|
||||||
}
|
}
|
||||||
while (++index < length) {
|
|
||||||
if (iterator(iterable[index], index, collection) === false) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
baseForOwn(collection, iterator);
|
|
||||||
}
|
}
|
||||||
return collection;
|
return collection;
|
||||||
}
|
}
|
||||||
@@ -1618,20 +1615,15 @@
|
|||||||
* @returns {Array|Object|string} Returns `collection`.
|
* @returns {Array|Object|string} Returns `collection`.
|
||||||
*/
|
*/
|
||||||
function baseEachRight(collection, iterator) {
|
function baseEachRight(collection, iterator) {
|
||||||
var iterable = collection,
|
var length = collection ? collection.length : 0;
|
||||||
length = collection ? collection.length : 0;
|
if (!(typeof length == 'number' && length > -1 && length <= maxSafeInteger)) {
|
||||||
|
return baseForOwnRight(collection, iterator);
|
||||||
if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) {
|
}
|
||||||
if (support.unindexedChars && isString(iterable)) {
|
var iterable = toIterable(collection);
|
||||||
iterable = iterable.split('');
|
while (length--) {
|
||||||
|
if (iterator(iterable[length], length, collection) === false) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
while (length--) {
|
|
||||||
if (iterator(iterable[length], length, collection) === false) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
baseForOwnRight(collection, iterator);
|
|
||||||
}
|
}
|
||||||
return collection;
|
return collection;
|
||||||
}
|
}
|
||||||
@@ -2104,6 +2096,7 @@
|
|||||||
*/
|
*/
|
||||||
function baseMerge(object, source, customizer, stackA, stackB) {
|
function baseMerge(object, source, customizer, stackA, stackB) {
|
||||||
var isSrcArr = isArrayLike(source);
|
var isSrcArr = isArrayLike(source);
|
||||||
|
|
||||||
(isSrcArr ? arrayEach : baseForOwn)(source, function(srcValue, key, source) {
|
(isSrcArr ? arrayEach : baseForOwn)(source, function(srcValue, key, source) {
|
||||||
var isArr = srcValue && isArrayLike(srcValue),
|
var isArr = srcValue && isArrayLike(srcValue),
|
||||||
isObj = srcValue && isPlainObject(srcValue),
|
isObj = srcValue && isPlainObject(srcValue),
|
||||||
@@ -2383,6 +2376,7 @@
|
|||||||
*/
|
*/
|
||||||
function compileFunction(source, varNames, varValues, sourceURL) {
|
function compileFunction(source, varNames, varValues, sourceURL) {
|
||||||
sourceURL = sourceURL ? ('\n/*\n//# sourceURL=' + sourceURL + '\n*/') : '';
|
sourceURL = sourceURL ? ('\n/*\n//# sourceURL=' + sourceURL + '\n*/') : '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// provide the compiled function's source by its `toString` method or
|
// provide the compiled function's source by its `toString` method or
|
||||||
// the `source` property as a convenience for inlining compiled templates
|
// the `source` property as a convenience for inlining compiled templates
|
||||||
@@ -2630,8 +2624,7 @@
|
|||||||
argsLength = arguments.length,
|
argsLength = arguments.length,
|
||||||
leftIndex = -1,
|
leftIndex = -1,
|
||||||
leftLength = partialArgs.length,
|
leftLength = partialArgs.length,
|
||||||
args = Array(argsLength + leftLength),
|
args = Array(argsLength + leftLength);
|
||||||
thisBinding = isBind ? thisArg : this;
|
|
||||||
|
|
||||||
while (++leftIndex < leftLength) {
|
while (++leftIndex < leftLength) {
|
||||||
args[leftIndex] = partialArgs[leftIndex];
|
args[leftIndex] = partialArgs[leftIndex];
|
||||||
@@ -2639,7 +2632,7 @@
|
|||||||
while (argsLength--) {
|
while (argsLength--) {
|
||||||
args[leftIndex++] = arguments[argsIndex++];
|
args[leftIndex++] = arguments[argsIndex++];
|
||||||
}
|
}
|
||||||
return (this instanceof wrapper ? Ctor : func).apply(thisBinding, args);
|
return (this instanceof wrapper ? Ctor : func).apply(isBind ? thisArg : this, args);
|
||||||
}
|
}
|
||||||
return wrapper;
|
return wrapper;
|
||||||
}
|
}
|
||||||
@@ -2918,6 +2911,23 @@
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts `collection` to an array if it is not an array-like value.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Array|Object|string} collection The collection to inspect.
|
||||||
|
* @returns {Array|Object} Returns the iterable object.
|
||||||
|
*/
|
||||||
|
function toIterable(collection) {
|
||||||
|
var length = collection ? collection.length : 0;
|
||||||
|
if (!(typeof length == 'number' && length > -1 && length <= maxSafeInteger)) {
|
||||||
|
return values(collection);
|
||||||
|
} else if (support.unindexedChars && isString(collection)) {
|
||||||
|
return collection.split('');
|
||||||
|
}
|
||||||
|
return collection || [];
|
||||||
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3330,8 +3340,9 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the index at which the first occurrence of `value` is found using
|
* Gets the index at which the first occurrence of `value` is found using
|
||||||
* strict equality for comparisons, i.e. `===`. If the array is already sorted
|
* strict equality for comparisons, i.e. `===`. If `fromIndex` is negative,
|
||||||
* providing `true` for `fromIndex` performs a faster binary search.
|
* it is used as the offset from the end of the collection. If `array` is
|
||||||
|
* sorted providing `true` for `fromIndex` performs a faster binary search.
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
* @memberOf _
|
* @memberOf _
|
||||||
@@ -3356,6 +3367,7 @@
|
|||||||
*/
|
*/
|
||||||
function indexOf(array, value, fromIndex) {
|
function indexOf(array, value, fromIndex) {
|
||||||
var length = array ? array.length : 0;
|
var length = array ? array.length : 0;
|
||||||
|
|
||||||
if (typeof fromIndex == 'number') {
|
if (typeof fromIndex == 'number') {
|
||||||
fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0);
|
fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0);
|
||||||
} else if (fromIndex) {
|
} else if (fromIndex) {
|
||||||
@@ -4234,8 +4246,10 @@
|
|||||||
* // => ['fred', 'pebbles']
|
* // => ['fred', 'pebbles']
|
||||||
*/
|
*/
|
||||||
function at(collection) {
|
function at(collection) {
|
||||||
if (support.unindexedChars && isString(collection)) {
|
var length = collection ? collection.length : 0;
|
||||||
collection = collection.split('');
|
|
||||||
|
if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) {
|
||||||
|
collection = toIterable(collection);
|
||||||
}
|
}
|
||||||
return baseAt(collection, baseFlatten(arguments, false, false, 1));
|
return baseAt(collection, baseFlatten(arguments, false, false, 1));
|
||||||
}
|
}
|
||||||
@@ -4269,6 +4283,7 @@
|
|||||||
*/
|
*/
|
||||||
function contains(collection, target, fromIndex) {
|
function contains(collection, target, fromIndex) {
|
||||||
var length = collection ? collection.length : 0;
|
var length = collection ? collection.length : 0;
|
||||||
|
|
||||||
if (!(typeof length == 'number' && length > -1 && length <= maxSafeInteger)) {
|
if (!(typeof length == 'number' && length > -1 && length <= maxSafeInteger)) {
|
||||||
collection = values(collection);
|
collection = values(collection);
|
||||||
length = collection.length;
|
length = collection.length;
|
||||||
@@ -5022,12 +5037,12 @@
|
|||||||
* // => [4, 5, 2, 3, 0, 1]
|
* // => [4, 5, 2, 3, 0, 1]
|
||||||
*/
|
*/
|
||||||
function reduceRight(collection, iterator, accumulator, thisArg) {
|
function reduceRight(collection, iterator, accumulator, thisArg) {
|
||||||
var noaccum = arguments.length < 3;
|
var initFromCollection = arguments.length < 3;
|
||||||
iterator = lodash.callback(iterator, thisArg, 4);
|
iterator = lodash.callback(iterator, thisArg, 4);
|
||||||
|
|
||||||
baseEachRight(collection, function(value, index, collection) {
|
baseEachRight(collection, function(value, index, collection) {
|
||||||
accumulator = noaccum
|
accumulator = initFromCollection
|
||||||
? (noaccum = false, value)
|
? (initFromCollection = false, value)
|
||||||
: iterator(accumulator, value, index, collection);
|
: iterator(accumulator, value, index, collection);
|
||||||
});
|
});
|
||||||
return accumulator;
|
return accumulator;
|
||||||
@@ -5095,14 +5110,9 @@
|
|||||||
* // => [3, 1]
|
* // => [3, 1]
|
||||||
*/
|
*/
|
||||||
function sample(collection, n, guard) {
|
function sample(collection, n, guard) {
|
||||||
var length = collection ? collection.length : 0;
|
collection = toIterable(collection);
|
||||||
|
|
||||||
if (!(typeof length == 'number' && length > -1 && length <= maxSafeInteger)) {
|
var length = collection.length;
|
||||||
collection = values(collection);
|
|
||||||
length = collection.length;
|
|
||||||
} else if (support.unindexedChars && isString(collection)) {
|
|
||||||
collection = collection.split('');
|
|
||||||
}
|
|
||||||
if (n == null || guard) {
|
if (n == null || guard) {
|
||||||
return length > 0 ? collection[baseRandom(0, length - 1)] : undefined;
|
return length > 0 ? collection[baseRandom(0, length - 1)] : undefined;
|
||||||
}
|
}
|
||||||
@@ -5127,21 +5137,25 @@
|
|||||||
* // => [4, 1, 3, 2]
|
* // => [4, 1, 3, 2]
|
||||||
*/
|
*/
|
||||||
function shuffle(collection) {
|
function shuffle(collection) {
|
||||||
var index = -1,
|
collection = toIterable(collection);
|
||||||
length = collection && collection.length,
|
|
||||||
result = Array(length < 0 ? 0 : length >>> 0);
|
var index = -1,
|
||||||
|
length = collection.length,
|
||||||
|
result = Array(length);
|
||||||
|
|
||||||
|
while (++index < length) {
|
||||||
|
var value = collection[index],
|
||||||
|
rand = baseRandom(0, index);
|
||||||
|
|
||||||
baseEach(collection, function(value) {
|
|
||||||
var rand = baseRandom(0, ++index);
|
|
||||||
result[index] = result[rand];
|
result[index] = result[rand];
|
||||||
result[rand] = value;
|
result[rand] = value;
|
||||||
});
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the size of the collection by returning `collection.length` for arrays
|
* Gets the size of the collection by returning `collection.length` for
|
||||||
* and array-like objects or the number of own enumerable properties for objects.
|
* array-like values or the number of own enumerable properties for objects.
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
* @memberOf _
|
* @memberOf _
|
||||||
@@ -5310,14 +5324,8 @@
|
|||||||
* // => [2, 3, 4]
|
* // => [2, 3, 4]
|
||||||
*/
|
*/
|
||||||
function toArray(collection) {
|
function toArray(collection) {
|
||||||
var length = collection ? collection.length : 0;
|
var iterable = toIterable(collection);
|
||||||
|
return iterable === collection ? slice(collection) : iterable;
|
||||||
if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) {
|
|
||||||
return (support.unindexedChars && isString(collection))
|
|
||||||
? collection.split('')
|
|
||||||
: slice(collection);
|
|
||||||
}
|
|
||||||
return values(collection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -5449,7 +5457,8 @@
|
|||||||
function bindAll(object) {
|
function bindAll(object) {
|
||||||
return baseBindAll(object, arguments.length > 1
|
return baseBindAll(object, arguments.length > 1
|
||||||
? baseFlatten(arguments, false, false, 1)
|
? baseFlatten(arguments, false, false, 1)
|
||||||
: functions(object));
|
: functions(object)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -6731,8 +6740,8 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a collection is empty. A value is considered empty unless it is
|
* Checks if a collection is empty. A value is considered empty unless it is
|
||||||
* an array, array-like object, or string with a length greater than `0` or
|
* an array-like value with a length greater than `0` or an object with own
|
||||||
* an object with own enumerable properties.
|
* enumerable properties.
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
* @memberOf _
|
* @memberOf _
|
||||||
@@ -6757,9 +6766,8 @@
|
|||||||
* // => false
|
* // => false
|
||||||
*/
|
*/
|
||||||
function isEmpty(value) {
|
function isEmpty(value) {
|
||||||
var result = true;
|
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return result;
|
return true;
|
||||||
}
|
}
|
||||||
var length = value.length;
|
var length = value.length;
|
||||||
if ((typeof length == 'number' && length > -1 && length <= maxSafeInteger) &&
|
if ((typeof length == 'number' && length > -1 && length <= maxSafeInteger) &&
|
||||||
@@ -6767,11 +6775,7 @@
|
|||||||
(typeof value == 'object' && isFunction(value.splice)))) {
|
(typeof value == 'object' && isFunction(value.splice)))) {
|
||||||
return !length;
|
return !length;
|
||||||
}
|
}
|
||||||
baseForOwn(value, function() {
|
return !keys(value).length;
|
||||||
result = false;
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -7207,7 +7211,7 @@
|
|||||||
while (++index < length) {
|
while (++index < length) {
|
||||||
result[index] = String(index);
|
result[index] = String(index);
|
||||||
}
|
}
|
||||||
// Lo-Dash skips the `constructor` property when it infers it's iterating
|
// Lo-Dash skips the `constructor` property when it infers it is iterating
|
||||||
// over a `prototype` object because IE < 9 can't set the `[[Enumerable]]`
|
// over a `prototype` object because IE < 9 can't set the `[[Enumerable]]`
|
||||||
// attribute of an existing property and the `constructor` property of a
|
// attribute of an existing property and the `constructor` property of a
|
||||||
// prototype defaults to non-enumerable.
|
// prototype defaults to non-enumerable.
|
||||||
@@ -7434,7 +7438,8 @@
|
|||||||
}
|
}
|
||||||
return basePick(Object(object), typeof predicate == 'function'
|
return basePick(Object(object), typeof predicate == 'function'
|
||||||
? lodash.callback(predicate, thisArg, 3)
|
? lodash.callback(predicate, thisArg, 3)
|
||||||
: baseFlatten(arguments, false, false, 1));
|
: baseFlatten(arguments, false, false, 1)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -7470,6 +7475,7 @@
|
|||||||
*/
|
*/
|
||||||
function transform(object, iterator, accumulator, thisArg) {
|
function transform(object, iterator, accumulator, thisArg) {
|
||||||
var isArr = isArrayLike(object);
|
var isArr = isArrayLike(object);
|
||||||
|
|
||||||
if (accumulator == null) {
|
if (accumulator == null) {
|
||||||
if (isArr) {
|
if (isArr) {
|
||||||
accumulator = [];
|
accumulator = [];
|
||||||
|
|||||||
Reference in New Issue
Block a user