mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-08 18:17:48 +00:00
Allow placeholders to persist through more than 1 curried call.
This commit is contained in:
95
lodash.js
95
lodash.js
@@ -1032,6 +1032,26 @@
|
|||||||
return object.index - other.index;
|
return object.index - other.index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of `placeholder` occurrences in `array`.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Array} array The array to inspect.
|
||||||
|
* @param {*} placeholder The placeholder to search for.
|
||||||
|
* @returns {number} Returns the placeholder count.
|
||||||
|
*/
|
||||||
|
function countHolders(array, placeholder) {
|
||||||
|
var length = array.length,
|
||||||
|
result = 0;
|
||||||
|
|
||||||
|
while (length--) {
|
||||||
|
if (array[length] === placeholder) {
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters.
|
* Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters.
|
||||||
*
|
*
|
||||||
@@ -1170,7 +1190,8 @@
|
|||||||
result = [];
|
result = [];
|
||||||
|
|
||||||
while (++index < length) {
|
while (++index < length) {
|
||||||
if (array[index] === placeholder) {
|
var value = array[index];
|
||||||
|
if (value === placeholder || value === PLACEHOLDER) {
|
||||||
array[index] = PLACEHOLDER;
|
array[index] = PLACEHOLDER;
|
||||||
result[++resIndex] = index;
|
result[++resIndex] = index;
|
||||||
}
|
}
|
||||||
@@ -3870,23 +3891,28 @@
|
|||||||
* @param {Array|Object} args The provided arguments.
|
* @param {Array|Object} args The provided arguments.
|
||||||
* @param {Array} partials The arguments to prepend to those provided.
|
* @param {Array} partials The arguments to prepend to those provided.
|
||||||
* @param {Array} holders The `partials` placeholder indexes.
|
* @param {Array} holders The `partials` placeholder indexes.
|
||||||
|
* @params {boolean} [isCurried] Specify composing for a curried function.
|
||||||
* @returns {Array} Returns the new array of composed arguments.
|
* @returns {Array} Returns the new array of composed arguments.
|
||||||
*/
|
*/
|
||||||
function composeArgs(args, partials, holders) {
|
function composeArgs(args, partials, holders, isCurried) {
|
||||||
var holdersLength = holders.length,
|
var argsIndex = -1,
|
||||||
argsIndex = -1,
|
argsLength = args.length,
|
||||||
argsLength = nativeMax(args.length - holdersLength, 0),
|
holdersLength = holders.length,
|
||||||
leftIndex = -1,
|
leftIndex = -1,
|
||||||
leftLength = partials.length,
|
leftLength = partials.length,
|
||||||
result = Array(leftLength + argsLength);
|
rangeLength = nativeMax(argsLength - holdersLength, 0),
|
||||||
|
result = Array(leftLength + rangeLength),
|
||||||
|
isUncurried = !isCurried;
|
||||||
|
|
||||||
while (++leftIndex < leftLength) {
|
while (++leftIndex < leftLength) {
|
||||||
result[leftIndex] = partials[leftIndex];
|
result[leftIndex] = partials[leftIndex];
|
||||||
}
|
}
|
||||||
while (++argsIndex < holdersLength) {
|
while (++argsIndex < holdersLength) {
|
||||||
result[holders[argsIndex]] = args[argsIndex];
|
if (isUncurried || argsIndex < argsLength) {
|
||||||
|
result[holders[argsIndex]] = args[argsIndex];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (argsLength--) {
|
while (rangeLength--) {
|
||||||
result[leftIndex++] = args[argsIndex++];
|
result[leftIndex++] = args[argsIndex++];
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -3900,18 +3926,21 @@
|
|||||||
* @param {Array|Object} args The provided arguments.
|
* @param {Array|Object} args The provided arguments.
|
||||||
* @param {Array} partials The arguments to append to those provided.
|
* @param {Array} partials The arguments to append to those provided.
|
||||||
* @param {Array} holders The `partials` placeholder indexes.
|
* @param {Array} holders The `partials` placeholder indexes.
|
||||||
|
* @params {boolean} [isCurried] Specify composing for a curried function.
|
||||||
* @returns {Array} Returns the new array of composed arguments.
|
* @returns {Array} Returns the new array of composed arguments.
|
||||||
*/
|
*/
|
||||||
function composeArgsRight(args, partials, holders) {
|
function composeArgsRight(args, partials, holders, isCurried) {
|
||||||
var holdersIndex = -1,
|
var argsIndex = -1,
|
||||||
|
argsLength = args.length,
|
||||||
|
holdersIndex = -1,
|
||||||
holdersLength = holders.length,
|
holdersLength = holders.length,
|
||||||
argsIndex = -1,
|
|
||||||
argsLength = nativeMax(args.length - holdersLength, 0),
|
|
||||||
rightIndex = -1,
|
rightIndex = -1,
|
||||||
rightLength = partials.length,
|
rightLength = partials.length,
|
||||||
result = Array(argsLength + rightLength);
|
rangeLength = nativeMax(argsLength - holdersLength, 0),
|
||||||
|
result = Array(rangeLength + rightLength),
|
||||||
|
isUncurried = !isCurried;
|
||||||
|
|
||||||
while (++argsIndex < argsLength) {
|
while (++argsIndex < rangeLength) {
|
||||||
result[argsIndex] = args[argsIndex];
|
result[argsIndex] = args[argsIndex];
|
||||||
}
|
}
|
||||||
var offset = argsIndex;
|
var offset = argsIndex;
|
||||||
@@ -3919,7 +3948,9 @@
|
|||||||
result[offset + rightIndex] = partials[rightIndex];
|
result[offset + rightIndex] = partials[rightIndex];
|
||||||
}
|
}
|
||||||
while (++holdersIndex < holdersLength) {
|
while (++holdersIndex < holdersLength) {
|
||||||
result[offset + holders[holdersIndex]] = args[argsIndex++];
|
if (isUncurried || argsIndex < argsLength) {
|
||||||
|
result[offset + holders[holdersIndex]] = args[argsIndex++];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -4306,8 +4337,7 @@
|
|||||||
var isAry = bitmask & ARY_FLAG,
|
var isAry = bitmask & ARY_FLAG,
|
||||||
isBind = bitmask & BIND_FLAG,
|
isBind = bitmask & BIND_FLAG,
|
||||||
isBindKey = bitmask & BIND_KEY_FLAG,
|
isBindKey = bitmask & BIND_KEY_FLAG,
|
||||||
isCurry = bitmask & CURRY_FLAG,
|
isCurried = bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG),
|
||||||
isCurryRight = bitmask & CURRY_RIGHT_FLAG,
|
|
||||||
isFlip = bitmask & FLIP_FLAG,
|
isFlip = bitmask & FLIP_FLAG,
|
||||||
Ctor = isBindKey ? undefined : createCtorWrapper(func);
|
Ctor = isBindKey ? undefined : createCtorWrapper(func);
|
||||||
|
|
||||||
@@ -4319,33 +4349,34 @@
|
|||||||
while (index--) {
|
while (index--) {
|
||||||
args[index] = arguments[index];
|
args[index] = arguments[index];
|
||||||
}
|
}
|
||||||
|
if (isCurried) {
|
||||||
|
var placeholder = lodash.placeholder || wrapper.placeholder,
|
||||||
|
holdersCount = countHolders(args, placeholder);
|
||||||
|
}
|
||||||
if (partials) {
|
if (partials) {
|
||||||
args = composeArgs(args, partials, holders);
|
args = composeArgs(args, partials, holders, isCurried);
|
||||||
}
|
}
|
||||||
if (partialsRight) {
|
if (partialsRight) {
|
||||||
args = composeArgsRight(args, partialsRight, holdersRight);
|
args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
|
||||||
}
|
}
|
||||||
if (isCurry || isCurryRight) {
|
length -= holdersCount;
|
||||||
var placeholder = lodash.placeholder || wrapper.placeholder,
|
if (isCurried && length < arity) {
|
||||||
argsHolders = replaceHolders(args, placeholder);
|
var newHolders = replaceHolders(args, placeholder);
|
||||||
|
return createRecurryWrapper(
|
||||||
length -= argsHolders.length;
|
func, bitmask, createHybridWrapper, placeholder, thisArg, args,
|
||||||
if (length < arity) {
|
newHolders, argPos, ary, arity - length
|
||||||
return createRecurryWrapper(
|
);
|
||||||
func, bitmask, createHybridWrapper, placeholder, thisArg, args,
|
|
||||||
argsHolders, argPos, ary, arity - length
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
var thisBinding = isBind ? thisArg : this,
|
var thisBinding = isBind ? thisArg : this,
|
||||||
fn = isBindKey ? thisBinding[func] : func;
|
fn = isBindKey ? thisBinding[func] : func;
|
||||||
|
|
||||||
|
length = args.length;
|
||||||
if (argPos) {
|
if (argPos) {
|
||||||
args = reorder(args, argPos);
|
args = reorder(args, argPos);
|
||||||
} else if (isFlip && args.length > 1) {
|
} else if (isFlip && length > 1) {
|
||||||
args.reverse();
|
args.reverse();
|
||||||
}
|
}
|
||||||
if (isAry && ary < args.length) {
|
if (isAry && ary < length) {
|
||||||
args.length = ary;
|
args.length = ary;
|
||||||
}
|
}
|
||||||
if (this && this !== root && this instanceof wrapper) {
|
if (this && this !== root && this instanceof wrapper) {
|
||||||
|
|||||||
20
test/test.js
20
test/test.js
@@ -3612,6 +3612,16 @@
|
|||||||
assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), [1, 2, 3, 4]);
|
assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), [1, 2, 3, 4]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QUnit.test('should persist placeholders', function(assert) {
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
var curried = _.curry(fn),
|
||||||
|
ph = curried.placeholder,
|
||||||
|
actual = curried(ph, ph, ph, 'd')('a')(ph)('b')('c');
|
||||||
|
|
||||||
|
assert.deepEqual(actual, ['a', 'b', 'c', 'd']);
|
||||||
|
});
|
||||||
|
|
||||||
QUnit.test('should provide additional arguments after reaching the target arity', function(assert) {
|
QUnit.test('should provide additional arguments after reaching the target arity', function(assert) {
|
||||||
assert.expect(3);
|
assert.expect(3);
|
||||||
|
|
||||||
@@ -3745,6 +3755,16 @@
|
|||||||
assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), expected);
|
assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QUnit.test('should persist placeholders', function(assert) {
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
var curried = _.curryRight(fn),
|
||||||
|
ph = curried.placeholder,
|
||||||
|
actual = curried('a', ph, ph, ph)('b')(ph)('c')('d');
|
||||||
|
|
||||||
|
assert.deepEqual(actual, ['a', 'b', 'c', 'd']);
|
||||||
|
});
|
||||||
|
|
||||||
QUnit.test('should provide additional arguments after reaching the target arity', function(assert) {
|
QUnit.test('should provide additional arguments after reaching the target arity', function(assert) {
|
||||||
assert.expect(3);
|
assert.expect(3);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user