Add arrayCopy and use baseSlice in more functions.

This commit is contained in:
John-David Dalton
2015-01-07 20:58:17 -08:00
parent c6852f4b96
commit 2348ec40ee

View File

@@ -508,25 +508,6 @@
return -1; return -1;
} }
/**
* The base implementation of `_.slice` without support for `start` and `end`
* arguments.
*
* @private
* @param {Array} array The array to slice.
* @returns {Array} Returns the slice of `array`.
*/
function baseSlice(array) {
var index = -1,
length = array.length,
result = Array(length);
while (++index < length) {
result[index] = array[index];
}
return result;
}
/** /**
* The base implementation of `_.sortBy` and `_.sortByAll` which uses `comparer` * The base implementation of `_.sortBy` and `_.sortByAll` which uses `comparer`
* to define the sort order of `array` and replaces criteria objects with their * to define the sort order of `array` and replaces criteria objects with their
@@ -1113,7 +1094,7 @@
return value; return value;
} }
if (hasOwnProperty.call(value, '__wrapped__')) { if (hasOwnProperty.call(value, '__wrapped__')) {
return new LodashWrapper(value.__wrapped__, value.__chain__, baseSlice(value.__actions__)); return new LodashWrapper(value.__wrapped__, value.__chain__, arrayCopy(value.__actions__));
} }
} }
return new LodashWrapper(value); return new LodashWrapper(value);
@@ -1388,13 +1369,13 @@
views = this.views, views = this.views,
result = new LazyWrapper(this.wrapped); result = new LazyWrapper(this.wrapped);
result.actions = actions ? baseSlice(actions) : null; result.actions = actions ? arrayCopy(actions) : null;
result.dir = this.dir; result.dir = this.dir;
result.dropCount = this.dropCount; result.dropCount = this.dropCount;
result.filtered = this.filtered; result.filtered = this.filtered;
result.iteratees = iteratees ? baseSlice(iteratees) : null; result.iteratees = iteratees ? arrayCopy(iteratees) : null;
result.takeCount = this.takeCount; result.takeCount = this.takeCount;
result.views = views ? baseSlice(views) : null; result.views = views ? arrayCopy(views) : null;
return result; return result;
} }
@@ -1613,6 +1594,25 @@
return result; return result;
} }
/**
* Copies the values of `array` to `other`.
*
* @private
* @param {Array} array The array to copy.
* @param {Array} [other=[]] The array to copy values to.
* @returns {Array} Returns `other`.
*/
function arrayCopy(array, other) {
var index = -1,
length = array.length,
result = other || Array(length);
while (++index < length) {
result[index] = array[index];
}
return result;
}
/** /**
* A specialized version of `_.max` for arrays without support for iteratees. * A specialized version of `_.max` for arrays without support for iteratees.
* *
@@ -1886,7 +1886,7 @@
if (!isFunction(func)) { if (!isFunction(func)) {
throw new TypeError(FUNC_ERROR_TEXT); throw new TypeError(FUNC_ERROR_TEXT);
} }
return setTimeout(function() { func.apply(undefined, slice(args, fromIndex)); }, wait); return setTimeout(function() { func.apply(undefined, baseSlice(args, fromIndex)); }, wait);
} }
/** /**
@@ -2231,8 +2231,8 @@
* `customizer` functions. * `customizer` functions.
* *
* @private * @private
* @param {*} value The value to compare to `other`. * @param {*} value The value to compare.
* @param {*} other The value to compare to `value`. * @param {*} other The other value to compare.
* @param {Function} [customizer] The function to customize comparing values. * @param {Function} [customizer] The function to customize comparing values.
* @param {boolean} [isWhere] Specify performing partial comparisons. * @param {boolean} [isWhere] Specify performing partial comparisons.
* @param {Array} [stackA] Tracks traversed `value` objects. * @param {Array} [stackA] Tracks traversed `value` objects.
@@ -2263,8 +2263,8 @@
* objects with circular references to be compared. * objects with circular references to be compared.
* *
* @private * @private
* @param {Array} object The object to compare to `other`. * @param {Array} object The object to compare.
* @param {Array} other The object to compare to `value`. * @param {Array} other The other object to compare.
* @param {Function} equalFunc The function to determine equivalents of arbitrary values. * @param {Function} equalFunc The function to determine equivalents of arbitrary values.
* @param {Function} [customizer] The function to customize comparing objects. * @param {Function} [customizer] The function to customize comparing objects.
* @param {boolean} [isWhere] Specify performing partial comparisons. * @param {boolean} [isWhere] Specify performing partial comparisons.
@@ -2592,6 +2592,36 @@
return func; return func;
}; };
/**
* The base implementation of `_.slice` without an iteratee call guard.
*
* @private
* @param {Array} array The array to slice.
* @param {number} [start=0] The start position.
* @param {number} [end=array.length] The end position.
* @returns {Array} Returns the slice of `array`.
*/
function baseSlice(array, start, end) {
var index = -1,
length = array.length;
start = start == null ? 0 : (+start || 0);
if (start < 0) {
start = -start > length ? 0 : (length + start);
}
end = (typeof end == 'undefined' || end > length) ? length : (+end || 0);
if (end < 0) {
end += length;
}
length = start > end ? 0 : (end - start);
var result = Array(length);
while (++index < length) {
result[index] = array[index + start];
}
return result;
}
/** /**
* The base implementation of `_.some` without support for callback shorthands * The base implementation of `_.some` without support for callback shorthands
* or `this` binding. * or `this` binding.
@@ -3147,7 +3177,7 @@
length -= argsHolders.length; length -= argsHolders.length;
if (length < arity) { if (length < arity) {
var newArgPos = argPos ? baseSlice(argPos) : null, var newArgPos = argPos ? arrayCopy(argPos) : null,
newArity = nativeMax(arity - length, 0), newArity = nativeMax(arity - length, 0),
newsHolders = isCurry ? argsHolders : null, newsHolders = isCurry ? argsHolders : null,
newHoldersRight = isCurry ? null : argsHolders, newHoldersRight = isCurry ? null : argsHolders,
@@ -3309,8 +3339,8 @@
* partial deep comparisons. * partial deep comparisons.
* *
* @private * @private
* @param {Array} array The array to compare to `other`. * @param {Array} array The array to compare.
* @param {Array} other The array to compare to `value`. * @param {Array} other The other array to compare.
* @param {Function} equalFunc The function to determine equivalents of arbitrary values. * @param {Function} equalFunc The function to determine equivalents of arbitrary values.
* @param {Function} [customizer] The function to customize comparing arrays. * @param {Function} [customizer] The function to customize comparing arrays.
* @param {boolean} [isWhere] Specify performing partial comparisons. * @param {boolean} [isWhere] Specify performing partial comparisons.
@@ -3364,8 +3394,8 @@
* values of `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. * values of `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
* *
* @private * @private
* @param {Object} value The object to compare to `other`. * @param {Object} value The object to compare.
* @param {Object} other The object to compare to `object`. * @param {Object} other The other object to compare.
* @param {string} tag The `toStringTag` of the objects to compare. * @param {string} tag The `toStringTag` of the objects to compare.
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
*/ */
@@ -3401,8 +3431,8 @@
* partial deep comparisons. * partial deep comparisons.
* *
* @private * @private
* @param {Object} object The object to compare to `other`. * @param {Object} object The object to compare.
* @param {Object} other The object to compare to `value`. * @param {Object} other The other object to compare.
* @param {Function} equalFunc The function to determine equivalents of arbitrary values. * @param {Function} equalFunc The function to determine equivalents of arbitrary values.
* @param {Function} [customizer] The function to customize comparing values. * @param {Function} [customizer] The function to customize comparing values.
* @param {boolean} [isWhere] Specify performing partial comparisons. * @param {boolean} [isWhere] Specify performing partial comparisons.
@@ -3563,19 +3593,18 @@
* @returns {Array} Returns the initialized array clone. * @returns {Array} Returns the initialized array clone.
*/ */
function initArrayClone(array, isDeep) { function initArrayClone(array, isDeep) {
var index = -1, var length = array.length,
length = array.length,
result = new array.constructor(length); result = new array.constructor(length);
if (!isDeep) { if (length) {
while (++index < length) { if (!isDeep) {
result[index] = array[index]; arrayCopy(array, result);
}
// Add array properties assigned by `RegExp#exec`.
if (typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
result.index = array.index;
result.input = array.input;
} }
}
// Add array properties assigned by `RegExp#exec`.
if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
result.index = array.index;
result.input = array.input;
} }
return result; return result;
} }
@@ -3780,20 +3809,20 @@
var value = source[3]; var value = source[3];
if (value) { if (value) {
var partials = data[3]; var partials = data[3];
data[3] = partials ? composeArgs(partials, value, source[4]) : baseSlice(value); data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value);
data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : baseSlice(source[4]); data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]);
} }
// Compose partial right arguments. // Compose partial right arguments.
value = source[5]; value = source[5];
if (value) { if (value) {
partials = data[5]; partials = data[5];
data[5] = partials ? composeArgsRight(partials, value, source[6]) : baseSlice(value); data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value);
data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : baseSlice(source[6]); data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]);
} }
// Use source `argPos` if available. // Use source `argPos` if available.
value = source[7]; value = source[7];
if (value) { if (value) {
data[7] = baseSlice(value); data[7] = arrayCopy(value);
} }
// Use source `ary` if it's smaller. // Use source `ary` if it's smaller.
if (srcBitmask & ARY_FLAG) { if (srcBitmask & ARY_FLAG) {
@@ -3868,7 +3897,7 @@
function reorder(array, indexes) { function reorder(array, indexes) {
var arrLength = array.length, var arrLength = array.length,
length = nativeMin(indexes.length, arrLength), length = nativeMin(indexes.length, arrLength),
oldArray = baseSlice(array); oldArray = arrayCopy(array);
while (length--) { while (length--) {
var index = indexes[length]; var index = indexes[length];
@@ -4069,7 +4098,7 @@
result = Array(ceil(length / size)); result = Array(ceil(length / size));
while (index < length) { while (index < length) {
result[++resIndex] = slice(array, index, (index += size)); result[++resIndex] = baseSlice(array, index, (index += size));
} }
return result; return result;
} }
@@ -4162,10 +4191,14 @@
* // => [1, 2, 3] * // => [1, 2, 3]
*/ */
function drop(array, n, guard) { function drop(array, n, guard) {
var length = array ? array.length : 0;
if (!length) {
return [];
}
if (guard ? isIterateeCall(array, n, guard) : n == null) { if (guard ? isIterateeCall(array, n, guard) : n == null) {
n = 1; n = 1;
} }
return slice(array, n < 0 ? 0 : n); return baseSlice(array, n < 0 ? 0 : n);
} }
/** /**
@@ -4194,11 +4227,15 @@
* // => [1, 2, 3] * // => [1, 2, 3]
*/ */
function dropRight(array, n, guard) { function dropRight(array, n, guard) {
var length = array ? array.length : 0;
if (!length) {
return [];
}
if (guard ? isIterateeCall(array, n, guard) : n == null) { if (guard ? isIterateeCall(array, n, guard) : n == null) {
n = 1; n = 1;
} }
n = array ? (array.length - (+n || 0)) : 0; n = length - (+n || 0);
return slice(array, 0, n < 0 ? 0 : n); return baseSlice(array, 0, n < 0 ? 0 : n);
} }
/** /**
@@ -4243,10 +4280,12 @@
*/ */
function dropRightWhile(array, predicate, thisArg) { function dropRightWhile(array, predicate, thisArg) {
var length = array ? array.length : 0; var length = array ? array.length : 0;
if (!length) {
return [];
}
predicate = getCallback(predicate, thisArg, 3); predicate = getCallback(predicate, thisArg, 3);
while (length-- && predicate(array[length], length, array)) {} while (length-- && predicate(array[length], length, array)) {}
return slice(array, 0, length + 1); return baseSlice(array, 0, length + 1);
} }
/** /**
@@ -4290,12 +4329,14 @@
* // => ['pebbles'] * // => ['pebbles']
*/ */
function dropWhile(array, predicate, thisArg) { function dropWhile(array, predicate, thisArg) {
var index = -1, var length = array ? array.length : 0;
length = array ? array.length : 0; if (!length) {
return [];
}
var index = -1;
predicate = getCallback(predicate, thisArg, 3); predicate = getCallback(predicate, thisArg, 3);
while (++index < length && predicate(array[index], index, array)) {} while (++index < length && predicate(array[index], index, array)) {}
return slice(array, index); return baseSlice(array, index);
} }
/** /**
@@ -4817,32 +4858,15 @@
* @returns {Array} Returns the slice of `array`. * @returns {Array} Returns the slice of `array`.
*/ */
function slice(array, start, end) { function slice(array, start, end) {
var index = -1, var length = array ? array.length : 0;
length = array ? array.length : 0, if (!length) {
endType = typeof end; return [];
}
if (end && endType != 'number' && isIterateeCall(array, start, end)) { if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
start = 0; start = 0;
end = length; end = length;
} }
start = start == null ? 0 : (+start || 0); return baseSlice(array, start, end);
if (start < 0) {
start = -start > length ? 0 : (length + start);
}
end = (endType == 'undefined' || end > length) ? length : (+end || 0);
if (end < 0) {
end += length;
}
if (end && end == length && !start) {
return baseSlice(array);
}
length = start > end ? 0 : (end - start);
var result = Array(length);
while (++index < length) {
result[index] = array[index + start];
}
return result;
} }
/** /**
@@ -4951,10 +4975,14 @@
* // => [] * // => []
*/ */
function take(array, n, guard) { function take(array, n, guard) {
var length = array ? array.length : 0;
if (!length) {
return [];
}
if (guard ? isIterateeCall(array, n, guard) : n == null) { if (guard ? isIterateeCall(array, n, guard) : n == null) {
n = 1; n = 1;
} }
return slice(array, 0, n < 0 ? 0 : n); return baseSlice(array, 0, n < 0 ? 0 : n);
} }
/** /**
@@ -4983,11 +5011,15 @@
* // => [] * // => []
*/ */
function takeRight(array, n, guard) { function takeRight(array, n, guard) {
var length = array ? array.length : 0;
if (!length) {
return [];
}
if (guard ? isIterateeCall(array, n, guard) : n == null) { if (guard ? isIterateeCall(array, n, guard) : n == null) {
n = 1; n = 1;
} }
n = array ? (array.length - (+n || 0)) : 0; n = length - (+n || 0);
return slice(array, n < 0 ? 0 : n); return baseSlice(array, n < 0 ? 0 : n);
} }
/** /**
@@ -5032,10 +5064,12 @@
*/ */
function takeRightWhile(array, predicate, thisArg) { function takeRightWhile(array, predicate, thisArg) {
var length = array ? array.length : 0; var length = array ? array.length : 0;
if (!length) {
return [];
}
predicate = getCallback(predicate, thisArg, 3); predicate = getCallback(predicate, thisArg, 3);
while (length-- && predicate(array[length], length, array)) {} while (length-- && predicate(array[length], length, array)) {}
return slice(array, length + 1); return baseSlice(array, length + 1);
} }
/** /**
@@ -5079,12 +5113,14 @@
* // => ['barney', 'fred'] * // => ['barney', 'fred']
*/ */
function takeWhile(array, predicate, thisArg) { function takeWhile(array, predicate, thisArg) {
var index = -1, var length = array ? array.length : 0;
length = array ? array.length : 0; if (!length) {
return [];
}
var index = -1;
predicate = getCallback(predicate, thisArg, 3); predicate = getCallback(predicate, thisArg, 3);
while (++index < length && predicate(array[index], index, array)) {} while (++index < length && predicate(array[index], index, array)) {}
return slice(array, 0, index); return baseSlice(array, 0, index);
} }
/** /**
@@ -5228,7 +5264,7 @@
* // => [2, 3, 4] * // => [2, 3, 4]
*/ */
function without(array) { function without(array) {
return baseDifference(array, slice(arguments, 1)); return baseDifference(array, baseSlice(arguments, 1));
} }
/** /**
@@ -5977,7 +6013,7 @@
* // => [['1', '2', '3'], ['4', '5', '6']] * // => [['1', '2', '3'], ['4', '5', '6']]
*/ */
function invoke(collection, methodName) { function invoke(collection, methodName) {
return baseInvoke(collection, methodName, slice(arguments, 2)); return baseInvoke(collection, methodName, baseSlice(arguments, 2));
} }
/** /**
@@ -6556,7 +6592,7 @@
} }
return (lodash.support.unindexedChars && isString(collection)) return (lodash.support.unindexedChars && isString(collection))
? collection.split('') ? collection.split('')
: baseSlice(collection); : arrayCopy(collection);
} }
/** /**
@@ -6750,7 +6786,7 @@
function bind(func, thisArg) { function bind(func, thisArg) {
var bitmask = BIND_FLAG; var bitmask = BIND_FLAG;
if (arguments.length > 2) { if (arguments.length > 2) {
var partials = slice(arguments, 2), var partials = baseSlice(arguments, 2),
holders = replaceHolders(partials, bind.placeholder); holders = replaceHolders(partials, bind.placeholder);
bitmask |= PARTIAL_FLAG; bitmask |= PARTIAL_FLAG;
@@ -6839,7 +6875,7 @@
function bindKey(object, key) { function bindKey(object, key) {
var bitmask = BIND_FLAG | BIND_KEY_FLAG; var bitmask = BIND_FLAG | BIND_KEY_FLAG;
if (arguments.length > 2) { if (arguments.length > 2) {
var partials = slice(arguments, 2), var partials = baseSlice(arguments, 2),
holders = replaceHolders(partials, bindKey.placeholder); holders = replaceHolders(partials, bindKey.placeholder);
bitmask |= PARTIAL_FLAG; bitmask |= PARTIAL_FLAG;
@@ -7402,7 +7438,7 @@
* // => 'hi fred' * // => 'hi fred'
*/ */
function partial(func) { function partial(func) {
var partials = slice(arguments, 1), var partials = baseSlice(arguments, 1),
holders = replaceHolders(partials, partial.placeholder); holders = replaceHolders(partials, partial.placeholder);
return createWrapper(func, PARTIAL_FLAG, null, partials, holders); return createWrapper(func, PARTIAL_FLAG, null, partials, holders);
@@ -7440,7 +7476,7 @@
* // => 'hello fred' * // => 'hello fred'
*/ */
function partialRight(func) { function partialRight(func) {
var partials = slice(arguments, 1), var partials = baseSlice(arguments, 1),
holders = replaceHolders(partials, partialRight.placeholder); holders = replaceHolders(partials, partialRight.placeholder);
return createWrapper(func, PARTIAL_RIGHT_FLAG, null, partials, holders); return createWrapper(func, PARTIAL_RIGHT_FLAG, null, partials, holders);
@@ -7840,8 +7876,8 @@
* @static * @static
* @memberOf _ * @memberOf _
* @category Lang * @category Lang
* @param {*} value The value to compare to `other`. * @param {*} value The value to compare.
* @param {*} other The value to compare to `value`. * @param {*} other The other value to compare.
* @param {Function} [customizer] The function to customize comparing values. * @param {Function} [customizer] The function to customize comparing values.
* @param {*} [thisArg] The `this` binding of `customizer`. * @param {*} [thisArg] The `this` binding of `customizer`.
* @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
@@ -8351,7 +8387,7 @@
if (object == null) { if (object == null) {
return object; return object;
} }
var args = baseSlice(arguments); var args = arrayCopy(arguments);
args.push(assignDefaults); args.push(assignDefaults);
return assign.apply(undefined, args); return assign.apply(undefined, args);
} }
@@ -10232,7 +10268,7 @@
var chainAll = this.__chain__; var chainAll = this.__chain__;
if (chain || chainAll) { if (chain || chainAll) {
var result = object(this.__wrapped__); var result = object(this.__wrapped__);
(result.__actions__ = baseSlice(this.__actions__)).push({ 'func': func, 'args': arguments, 'thisArg': object }); (result.__actions__ = arrayCopy(this.__actions__)).push({ 'func': func, 'args': arguments, 'thisArg': object });
result.__chain__ = chainAll; result.__chain__ = chainAll;
return result; return result;
} }