Add castRest, flatRest, and overRest helpers.

This commit is contained in:
John-David Dalton
2016-08-27 10:42:55 -07:00
parent a0ecdfff0b
commit 3c03d4a1f3

111
lodash.js
View File

@@ -3829,24 +3829,7 @@
* @returns {Function} Returns the new function.
*/
function baseRest(func, start) {
start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
return setToString(function() {
var args = arguments,
index = -1,
length = nativeMax(args.length - start, 0),
array = Array(length);
while (++index < length) {
array[index] = args[start + index];
}
index = -1;
var otherArgs = Array(start + 1);
while (++index < start) {
otherArgs[index] = args[index];
}
otherArgs[start] = array;
return apply(func, this, otherArgs);
}, func + '');
return setToString(overRest(func, start, identity), func + '');
}
/**
@@ -4316,6 +4299,17 @@
return isArray(value) ? value : stringToPath(value);
}
/**
* A `baseRest` alias which can be replaced with `identity` by module
* replacement plugins.
*
* @private
* @type {Function}
* @param {Function} func The function to apply a rest parameter to.
* @returns {Function} Returns the new function.
*/
var castRest = baseRest;
/**
* Casts `array` to a slice if it's needed.
*
@@ -4929,9 +4923,7 @@
* @returns {Function} Returns the new flow function.
*/
function createFlow(fromRight) {
return baseRest(function(funcs) {
funcs = baseFlatten(funcs, 1);
return flatRest(function(funcs) {
var length = funcs.length,
index = length,
prereq = LodashWrapper.prototype.thru;
@@ -5114,11 +5106,8 @@
* @returns {Function} Returns the new over function.
*/
function createOver(arrayFunc) {
return baseRest(function(iteratees) {
iteratees = (iteratees.length == 1 && isArray(iteratees[0]))
? arrayMap(iteratees[0], baseUnary(getIteratee()))
: arrayMap(baseFlatten(iteratees, 1), baseUnary(getIteratee()));
return flatRest(function(iteratees) {
iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
return baseRest(function(args) {
var thisArg = this;
return arrayFunc(iteratees, function(iteratee) {
@@ -5643,6 +5632,17 @@
return result;
}
/**
* A specialized version of `baseRest` which flattens the rest array.
*
* @private
* @param {Function} func The function to apply a rest parameter to.
* @returns {Function} Returns the new function.
*/
function flatRest(func) {
return setToString(overRest(func, undefined, flatten), func + '');
}
/**
* Creates an array of own enumerable property names and symbols of `object`.
*
@@ -6290,6 +6290,36 @@
return result;
}
/**
* A specialized version of `baseRest` which transforms the rest array.
*
* @private
* @param {Function} func The function to apply a rest parameter to.
* @param {number} [start=func.length-1] The start position of the rest parameter.
* @param {Function} transform The rest array transform.
* @returns {Function} Returns the new function.
*/
function overRest(func, start, transform) {
start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
return function() {
var args = arguments,
index = -1,
length = nativeMax(args.length - start, 0),
array = Array(length);
while (++index < length) {
array[index] = args[start + index];
}
index = -1;
var otherArgs = Array(start + 1);
while (++index < start) {
otherArgs[index] = args[index];
}
otherArgs[start] = transform(array);
return apply(func, this, otherArgs);
};
}
/**
* Gets the parent value at `path` of `object`.
*
@@ -7487,9 +7517,7 @@
* console.log(pulled);
* // => ['b', 'd']
*/
var pullAt = baseRest(function(array, indexes) {
indexes = baseFlatten(indexes, 1);
var pullAt = flatRest(function(array, indexes) {
var length = array ? array.length : 0,
result = baseAt(array, indexes);
@@ -8505,8 +8533,7 @@
* _(object).at(['a[0].b.c', 'a[1]']).value();
* // => [3, 4]
*/
var wrapperAt = baseRest(function(paths) {
paths = baseFlatten(paths, 1);
var wrapperAt = flatRest(function(paths) {
var length = paths.length,
start = length ? paths[0] : 0,
value = this.__wrapped__,
@@ -10366,7 +10393,7 @@
* func(10, 5);
* // => [100, 10]
*/
var overArgs = baseRest(function(func, transforms) {
var overArgs = castRest(function(func, transforms) {
transforms = (transforms.length == 1 && isArray(transforms[0]))
? arrayMap(transforms[0], baseUnary(getIteratee()))
: arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
@@ -10480,8 +10507,8 @@
* rearged('b', 'c', 'a')
* // => ['a', 'b', 'c']
*/
var rearg = baseRest(function(func, indexes) {
return createWrap(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes, 1));
var rearg = flatRest(function(func, indexes) {
return createWrap(func, REARG_FLAG, undefined, undefined, undefined, indexes);
});
/**
@@ -12429,9 +12456,7 @@
* _.at(object, ['a[0].b.c', 'a[1]']);
* // => [3, 4]
*/
var at = baseRest(function(object, paths) {
return baseAt(object, baseFlatten(paths, 1));
});
var at = flatRest(baseAt);
/**
* Creates an object that inherits from the `prototype` object. If a
@@ -13166,11 +13191,11 @@
* _.omit(object, ['a', 'c']);
* // => { 'b': '2' }
*/
var omit = baseRest(function(object, props) {
var omit = flatRest(function(object, props) {
if (object == null) {
return {};
}
props = arrayMap(baseFlatten(props, 1), toKey);
props = arrayMap(props, toKey);
return basePick(object, baseDifference(getAllKeysIn(object), props));
});
@@ -13215,8 +13240,8 @@
* _.pick(object, ['a', 'c']);
* // => { 'a': 1, 'c': 3 }
*/
var pick = baseRest(function(object, props) {
return object == null ? {} : basePick(object, arrayMap(baseFlatten(props, 1), toKey));
var pick = flatRest(function(object, props) {
return object == null ? {} : basePick(object, arrayMap(props, toKey));
});
/**
@@ -14923,8 +14948,8 @@
* jQuery(element).on('click', view.click);
* // => Logs 'clicked docs' when clicked.
*/
var bindAll = baseRest(function(object, methodNames) {
arrayEach(baseFlatten(methodNames, 1), function(key) {
var bindAll = flatRest(function(object, methodNames) {
arrayEach(methodNames, function(key) {
key = toKey(key);
baseAssignValue(object, key, bind(object[key], object));
});