mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-10 19:07:49 +00:00
Add fp.assignAllWith, fp.extendAllWith, and fp.mergeAllWith.
This commit is contained in:
@@ -71,11 +71,11 @@ function createCloner(func) {
|
|||||||
* @param {Function} cloner The function to clone arguments.
|
* @param {Function} cloner The function to clone arguments.
|
||||||
* @returns {Function} Returns the new immutable function.
|
* @returns {Function} Returns the new immutable function.
|
||||||
*/
|
*/
|
||||||
function immutWrap(func, cloner) {
|
function wrapImmutable(func, cloner) {
|
||||||
return function() {
|
return function() {
|
||||||
var length = arguments.length;
|
var length = arguments.length;
|
||||||
if (!length) {
|
if (!length) {
|
||||||
return result;
|
return;
|
||||||
}
|
}
|
||||||
var args = Array(length);
|
var args = Array(length);
|
||||||
while (length--) {
|
while (length--) {
|
||||||
@@ -218,6 +218,77 @@ function baseConvert(util, name, func, options) {
|
|||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Casts `func` to a function with an arity capped iteratee if needed.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {string} name The name of the function to inspect.
|
||||||
|
* @param {Function} func The function to inspect.
|
||||||
|
* @returns {Function} Returns the cast function.
|
||||||
|
*/
|
||||||
|
function castCap(name, func) {
|
||||||
|
if (config.cap) {
|
||||||
|
var indexes = mapping.iterateeRearg[name];
|
||||||
|
if (indexes) {
|
||||||
|
return iterateeRearg(func, indexes);
|
||||||
|
}
|
||||||
|
var n = !isLib && mapping.iterateeAry[name];
|
||||||
|
if (n) {
|
||||||
|
return iterateeAry(func, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Casts `func` to a curried function if needed.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {string} name The name of the function to inspect.
|
||||||
|
* @param {Function} func The function to inspect.
|
||||||
|
* @param {number} n The arity of `func`.
|
||||||
|
* @returns {Function} Returns the cast function.
|
||||||
|
*/
|
||||||
|
function castCurry(name, func, n) {
|
||||||
|
return (forceCurry || (config.curry && n > 1))
|
||||||
|
? curry(func, n)
|
||||||
|
: func;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Casts `func` to a fixed arity function if needed.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {string} name The name of the function to inspect.
|
||||||
|
* @param {Function} func The function to inspect.
|
||||||
|
* @param {number} n The arity cap.
|
||||||
|
* @returns {Function} Returns the cast function.
|
||||||
|
*/
|
||||||
|
function castFixed(name, func, n) {
|
||||||
|
if (config.fixed && (forceFixed || !mapping.skipFixed[name])) {
|
||||||
|
var data = mapping.methodSpread[name],
|
||||||
|
start = data && data.start;
|
||||||
|
|
||||||
|
return start === undefined ? ary(func, n) : spread(func, start);
|
||||||
|
}
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Casts `func` to an rearged function if needed.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {string} name The name of the function to inspect.
|
||||||
|
* @param {Function} func The function to inspect.
|
||||||
|
* @param {number} n The arity of `func`.
|
||||||
|
* @returns {Function} Returns the cast function.
|
||||||
|
*/
|
||||||
|
function castRearg(name, func, n) {
|
||||||
|
return (config.rearg && n > 1 && (forceRearg || !mapping.skipRearg[name]))
|
||||||
|
? rearg(func, mapping.methodRearg[name] || mapping.aryRearg[n])
|
||||||
|
: func;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a clone of `object` by `path`.
|
* Creates a clone of `object` by `path`.
|
||||||
*
|
*
|
||||||
@@ -354,42 +425,27 @@ function baseConvert(util, name, func, options) {
|
|||||||
}
|
}
|
||||||
else if (config.immutable) {
|
else if (config.immutable) {
|
||||||
if (mutateMap.array[name]) {
|
if (mutateMap.array[name]) {
|
||||||
wrapped = immutWrap(func, cloneArray);
|
wrapped = wrapImmutable(func, cloneArray);
|
||||||
}
|
}
|
||||||
else if (mutateMap.object[name]) {
|
else if (mutateMap.object[name]) {
|
||||||
wrapped = immutWrap(func, createCloner(func));
|
wrapped = wrapImmutable(func, createCloner(func));
|
||||||
}
|
}
|
||||||
else if (mutateMap.set[name]) {
|
else if (mutateMap.set[name]) {
|
||||||
wrapped = immutWrap(func, cloneByPath);
|
wrapped = wrapImmutable(func, cloneByPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
each(aryMethodKeys, function(aryKey) {
|
each(aryMethodKeys, function(aryKey) {
|
||||||
each(mapping.aryMethod[aryKey], function(otherName) {
|
each(mapping.aryMethod[aryKey], function(otherName) {
|
||||||
if (name == otherName) {
|
if (name == otherName) {
|
||||||
var aryN = !isLib && mapping.iterateeAry[name],
|
var spreadData = mapping.methodSpread[name],
|
||||||
reargIndexes = mapping.iterateeRearg[name],
|
afterRearg = spreadData && spreadData.afterRearg;
|
||||||
spreadStart = mapping.methodSpread[name];
|
|
||||||
|
|
||||||
result = wrapped;
|
result = afterRearg
|
||||||
if (config.fixed && (forceFixed || !mapping.skipFixed[name])) {
|
? castFixed(name, castRearg(name, wrapped, aryKey), aryKey)
|
||||||
result = spreadStart === undefined
|
: castRearg(name, castFixed(name, wrapped, aryKey), aryKey);
|
||||||
? ary(result, aryKey)
|
|
||||||
: spread(result, spreadStart);
|
result = castCap(name, result);
|
||||||
}
|
result = castCurry(name, result, aryKey);
|
||||||
if (config.rearg && aryKey > 1 && (forceRearg || !mapping.skipRearg[name])) {
|
|
||||||
result = rearg(result, mapping.methodRearg[name] || mapping.aryRearg[aryKey]);
|
|
||||||
}
|
|
||||||
if (config.cap) {
|
|
||||||
if (reargIndexes) {
|
|
||||||
result = iterateeRearg(result, reargIndexes);
|
|
||||||
} else if (aryN) {
|
|
||||||
result = iterateeAry(result, aryN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (forceCurry || (config.curry && aryKey > 1)) {
|
|
||||||
forceCurry && console.log(forceCurry, name);
|
|
||||||
result = curry(result, aryKey);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ exports.aliasToReal = {
|
|||||||
'entriesIn': 'toPairsIn',
|
'entriesIn': 'toPairsIn',
|
||||||
'extend': 'assignIn',
|
'extend': 'assignIn',
|
||||||
'extendAll': 'assignInAll',
|
'extendAll': 'assignInAll',
|
||||||
|
'extendAllWith': 'assignInAllWith',
|
||||||
'extendWith': 'assignInWith',
|
'extendWith': 'assignInWith',
|
||||||
'first': 'head',
|
'first': 'head',
|
||||||
|
|
||||||
@@ -76,27 +77,27 @@ exports.aryMethod = {
|
|||||||
'trimStart', 'uniqueId', 'words'
|
'trimStart', 'uniqueId', 'words'
|
||||||
],
|
],
|
||||||
'2': [
|
'2': [
|
||||||
'add', 'after', 'ary', 'assign', 'assignIn', 'at', 'before', 'bind', 'bindAll',
|
'add', 'after', 'ary', 'assign', 'assignAllWith', 'assignIn', 'assignInAllWith',
|
||||||
'bindKey', 'chunk', 'cloneDeepWith', 'cloneWith', 'concat', 'countBy', 'curryN',
|
'at', 'before', 'bind', 'bindAll', 'bindKey', 'chunk', 'cloneDeepWith',
|
||||||
'curryRightN', 'debounce', 'defaults', 'defaultsDeep', 'defaultTo', 'delay',
|
'cloneWith', 'concat', 'countBy', 'curryN', 'curryRightN', 'debounce',
|
||||||
'difference', 'divide', 'drop', 'dropRight', 'dropRightWhile', 'dropWhile',
|
'defaults', 'defaultsDeep', 'defaultTo', 'delay', 'difference', 'divide',
|
||||||
'endsWith', 'eq', 'every', 'filter', 'find', 'findIndex', 'findKey', 'findLast',
|
'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith', 'eq', 'every',
|
||||||
'findLastIndex', 'findLastKey', 'flatMap', 'flatMapDeep', 'flattenDepth',
|
'filter', 'find', 'findIndex', 'findKey', 'findLast', 'findLastIndex',
|
||||||
'forEach', 'forEachRight', 'forIn', 'forInRight', 'forOwn', 'forOwnRight',
|
'findLastKey', 'flatMap', 'flatMapDeep', 'flattenDepth', 'forEach',
|
||||||
'get', 'groupBy', 'gt', 'gte', 'has', 'hasIn', 'includes', 'indexOf',
|
'forEachRight', 'forIn', 'forInRight', 'forOwn', 'forOwnRight', 'get',
|
||||||
'intersection', 'invertBy', 'invoke', 'invokeMap', 'isEqual', 'isMatch',
|
'groupBy', 'gt', 'gte', 'has', 'hasIn', 'includes', 'indexOf', 'intersection',
|
||||||
'join', 'keyBy', 'lastIndexOf', 'lt', 'lte', 'map', 'mapKeys', 'mapValues',
|
'invertBy', 'invoke', 'invokeMap', 'isEqual', 'isMatch', 'join', 'keyBy',
|
||||||
'matchesProperty', 'maxBy', 'meanBy', 'merge', 'minBy', 'multiply', 'nth',
|
'lastIndexOf', 'lt', 'lte', 'map', 'mapKeys', 'mapValues', 'matchesProperty',
|
||||||
'omit', 'omitBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt',
|
'maxBy', 'meanBy', 'merge', 'minBy', 'multiply', 'nth', 'omit', 'omitBy',
|
||||||
'partial', 'partialRight', 'partition', 'pick', 'pickBy', 'pull', 'pullAll',
|
'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt', 'partial', 'partialRight',
|
||||||
'pullAt', 'random', 'range', 'rangeRight', 'rearg', 'reject', 'remove',
|
'partition', 'pick', 'pickBy', 'pull', 'pullAll', 'pullAt', 'random', 'range',
|
||||||
'repeat', 'restFrom', 'result', 'sampleSize', 'some', 'sortBy', 'sortedIndex',
|
'rangeRight', 'rearg', 'reject', 'remove', 'repeat', 'restFrom', 'result',
|
||||||
'sortedIndexOf', 'sortedLastIndex', 'sortedLastIndexOf', 'sortedUniqBy',
|
'sampleSize', 'some', 'sortBy', 'sortedIndex', 'sortedIndexOf', 'sortedLastIndex',
|
||||||
'split', 'spreadFrom', 'startsWith', 'subtract', 'sumBy', 'take', 'takeRight',
|
'sortedLastIndexOf', 'sortedUniqBy', 'split', 'spreadFrom', 'startsWith',
|
||||||
'takeRightWhile', 'takeWhile', 'tap', 'throttle', 'thru', 'times', 'trimChars',
|
'subtract', 'sumBy', 'take', 'takeRight', 'takeRightWhile', 'takeWhile', 'tap',
|
||||||
'trimCharsEnd', 'trimCharsStart', 'truncate', 'union', 'uniqBy', 'uniqWith',
|
'throttle', 'thru', 'times', 'trimChars', 'trimCharsEnd', 'trimCharsStart',
|
||||||
'unset', 'unzipWith', 'without', 'wrap', 'xor', 'zip', 'zipObject',
|
'truncate', 'union', 'uniqBy', 'uniqWith', 'unset', 'unzipWith', 'without',
|
||||||
'zipObjectDeep'
|
'wrap', 'xor', 'zip', 'zipObject', 'zipObjectDeep'
|
||||||
],
|
],
|
||||||
'3': [
|
'3': [
|
||||||
'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith',
|
'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith',
|
||||||
@@ -167,7 +168,9 @@ exports.iterateeRearg = {
|
|||||||
|
|
||||||
/** Used to map method names to rearg configs. */
|
/** Used to map method names to rearg configs. */
|
||||||
exports.methodRearg = {
|
exports.methodRearg = {
|
||||||
|
'assignInAllWith': [1, 2, 0],
|
||||||
'assignInWith': [1, 2, 0],
|
'assignInWith': [1, 2, 0],
|
||||||
|
'assignAllWith': [1, 2, 0],
|
||||||
'assignWith': [1, 2, 0],
|
'assignWith': [1, 2, 0],
|
||||||
'differenceBy': [1, 2, 0],
|
'differenceBy': [1, 2, 0],
|
||||||
'differenceWith': [1, 2, 0],
|
'differenceWith': [1, 2, 0],
|
||||||
@@ -176,6 +179,7 @@ exports.methodRearg = {
|
|||||||
'intersectionWith': [1, 2, 0],
|
'intersectionWith': [1, 2, 0],
|
||||||
'isEqualWith': [1, 2, 0],
|
'isEqualWith': [1, 2, 0],
|
||||||
'isMatchWith': [2, 1, 0],
|
'isMatchWith': [2, 1, 0],
|
||||||
|
'mergeAllWith': [1, 2, 0],
|
||||||
'mergeWith': [1, 2, 0],
|
'mergeWith': [1, 2, 0],
|
||||||
'padChars': [2, 1, 0],
|
'padChars': [2, 1, 0],
|
||||||
'padCharsEnd': [2, 1, 0],
|
'padCharsEnd': [2, 1, 0],
|
||||||
@@ -195,16 +199,19 @@ exports.methodRearg = {
|
|||||||
|
|
||||||
/** Used to map method names to spread configs. */
|
/** Used to map method names to spread configs. */
|
||||||
exports.methodSpread = {
|
exports.methodSpread = {
|
||||||
'assignAll': 0,
|
'assignAll': { 'start': 0 },
|
||||||
'assignInAll': 0,
|
'assignAllWith': { 'afterRearg': true, 'start': 1 },
|
||||||
'defaultsAll': 0,
|
'assignInAll': { 'start': 0 },
|
||||||
'defaultsDeepAll': 0,
|
'assignInAllWith': { 'afterRearg': true, 'start': 1 },
|
||||||
'invokeArgs': 2,
|
'defaultsAll': { 'start': 0 },
|
||||||
'invokeArgsMap': 2,
|
'defaultsDeepAll': { 'start': 0 },
|
||||||
'mergeAll': 0,
|
'invokeArgs': { 'start': 2 },
|
||||||
'partial': 1,
|
'invokeArgsMap': { 'start': 2 },
|
||||||
'partialRight': 1,
|
'mergeAll': { 'start': 0 },
|
||||||
'without': 1
|
'mergeAllWith': { 'afterRearg': true, 'start': 1 },
|
||||||
|
'partial': { 'start': 1 },
|
||||||
|
'partialRight': { 'start': 1 },
|
||||||
|
'without': { 'start': 1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Used to identify methods which mutate arrays or objects. */
|
/** Used to identify methods which mutate arrays or objects. */
|
||||||
@@ -222,8 +229,10 @@ exports.mutate = {
|
|||||||
'object': {
|
'object': {
|
||||||
'assign': true,
|
'assign': true,
|
||||||
'assignAll': true,
|
'assignAll': true,
|
||||||
|
'assignAllWith': true,
|
||||||
'assignIn': true,
|
'assignIn': true,
|
||||||
'assignInAll': true,
|
'assignInAll': true,
|
||||||
|
'assignInAllWith': true,
|
||||||
'assignInWith': true,
|
'assignInWith': true,
|
||||||
'assignWith': true,
|
'assignWith': true,
|
||||||
'defaults': true,
|
'defaults': true,
|
||||||
@@ -232,7 +241,8 @@ exports.mutate = {
|
|||||||
'defaultsDeepAll': true,
|
'defaultsDeepAll': true,
|
||||||
'merge': true,
|
'merge': true,
|
||||||
'mergeAll': true,
|
'mergeAll': true,
|
||||||
'mergeWith': true
|
'mergeAllWith': true,
|
||||||
|
'mergeWith': true,
|
||||||
},
|
},
|
||||||
'set': {
|
'set': {
|
||||||
'set': true,
|
'set': true,
|
||||||
@@ -273,7 +283,9 @@ exports.realToAlias = (function() {
|
|||||||
/** Used to map method names to other names. */
|
/** Used to map method names to other names. */
|
||||||
exports.remap = {
|
exports.remap = {
|
||||||
'assignAll': 'assign',
|
'assignAll': 'assign',
|
||||||
|
'assignAllWith': 'assignWith',
|
||||||
'assignInAll': 'assignIn',
|
'assignInAll': 'assignIn',
|
||||||
|
'assignInAllWith': 'assignInWith',
|
||||||
'curryN': 'curry',
|
'curryN': 'curry',
|
||||||
'curryRightN': 'curryRight',
|
'curryRightN': 'curryRight',
|
||||||
'defaultsAll': 'defaults',
|
'defaultsAll': 'defaults',
|
||||||
@@ -289,6 +301,7 @@ exports.remap = {
|
|||||||
'invokeArgsMap': 'invokeMap',
|
'invokeArgsMap': 'invokeMap',
|
||||||
'lastIndexOfFrom': 'lastIndexOf',
|
'lastIndexOfFrom': 'lastIndexOf',
|
||||||
'mergeAll': 'merge',
|
'mergeAll': 'merge',
|
||||||
|
'mergeAllWith': 'mergeWith',
|
||||||
'padChars': 'pad',
|
'padChars': 'pad',
|
||||||
'padCharsEnd': 'padEnd',
|
'padCharsEnd': 'padEnd',
|
||||||
'padCharsStart': 'padStart',
|
'padCharsStart': 'padStart',
|
||||||
|
|||||||
@@ -414,7 +414,7 @@
|
|||||||
'wrap'
|
'wrap'
|
||||||
];
|
];
|
||||||
|
|
||||||
var exceptions = _.difference(funcMethods.concat('matchesProperty'), ['cloneDeepWith', 'cloneWith', 'delay']),
|
var exceptions = _.without(funcMethods.concat('matchesProperty'), 'delay'),
|
||||||
expected = _.map(mapping.aryMethod[2], _.constant(true));
|
expected = _.map(mapping.aryMethod[2], _.constant(true));
|
||||||
|
|
||||||
var actual = _.map(mapping.aryMethod[2], function(methodName) {
|
var actual = _.map(mapping.aryMethod[2], function(methodName) {
|
||||||
@@ -775,6 +775,35 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_.each(['assignAllWith', 'assignInAllWith', 'extendAllWith'], function(methodName) {
|
||||||
|
var func = fp[methodName];
|
||||||
|
|
||||||
|
QUnit.test('`fp.' + methodName + '` should provide the correct `customizer` arguments', function(assert) {
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
var args;
|
||||||
|
|
||||||
|
func(function() {
|
||||||
|
args || (args = _.map(arguments, _.cloneDeep));
|
||||||
|
})([{ 'a': 1 }, { 'b': 2 }]);
|
||||||
|
|
||||||
|
assert.deepEqual(args, [undefined, 2, 'b', { 'a': 1 }, { 'b': 2 }]);
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('`fp.' + methodName + '` should not mutate values', function(assert) {
|
||||||
|
assert.expect(2);
|
||||||
|
|
||||||
|
var objects = [{ 'a': 1 }, { 'b': 2 }];
|
||||||
|
|
||||||
|
var actual = func(function(objValue, srcValue) {
|
||||||
|
return srcValue;
|
||||||
|
})(objects);
|
||||||
|
|
||||||
|
assert.deepEqual(objects[0], { 'a': 1 });
|
||||||
|
assert.deepEqual(actual, { 'a': 1, 'b': 2 });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
QUnit.module('fp.castArray');
|
QUnit.module('fp.castArray');
|
||||||
|
|||||||
Reference in New Issue
Block a user