mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-10 10:57:49 +00:00
Disable lazy optimizations if the iteratee has more than one param. [closes #997]
This commit is contained in:
@@ -11484,7 +11484,7 @@
|
|||||||
iteratees = result.__iteratees__ || (result.__iteratees__ = []);
|
iteratees = result.__iteratees__ || (result.__iteratees__ = []);
|
||||||
|
|
||||||
result.__filtered__ = result.__filtered__ || isFilter;
|
result.__filtered__ = result.__filtered__ || isFilter;
|
||||||
iteratees.push({ 'iteratee': getCallback(iteratee, thisArg, 3), 'type': index });
|
iteratees.push({ 'iteratee': getCallback(iteratee, thisArg, 1), 'type': index });
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -11554,7 +11554,7 @@
|
|||||||
lastIndex,
|
lastIndex,
|
||||||
isRight = this.__dir__ < 0;
|
isRight = this.__dir__ < 0;
|
||||||
|
|
||||||
predicate = getCallback(predicate, thisArg, 3);
|
predicate = getCallback(predicate, thisArg, 1);
|
||||||
return this.filter(function(value, index, array) {
|
return this.filter(function(value, index, array) {
|
||||||
done = done && (isRight ? index < lastIndex : index > lastIndex);
|
done = done && (isRight ? index < lastIndex : index > lastIndex);
|
||||||
lastIndex = index;
|
lastIndex = index;
|
||||||
@@ -11563,7 +11563,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
LazyWrapper.prototype.reject = function(predicate, thisArg) {
|
LazyWrapper.prototype.reject = function(predicate, thisArg) {
|
||||||
predicate = getCallback(predicate, thisArg, 3);
|
predicate = getCallback(predicate, thisArg, 1);
|
||||||
return this.filter(function(value, index, array) {
|
return this.filter(function(value, index, array) {
|
||||||
return !predicate(value, index, array);
|
return !predicate(value, index, array);
|
||||||
});
|
});
|
||||||
@@ -11587,6 +11587,7 @@
|
|||||||
// Add `LazyWrapper` methods to `lodash.prototype`.
|
// Add `LazyWrapper` methods to `lodash.prototype`.
|
||||||
baseForOwn(LazyWrapper.prototype, function(func, methodName) {
|
baseForOwn(LazyWrapper.prototype, function(func, methodName) {
|
||||||
var lodashFunc = lodash[methodName],
|
var lodashFunc = lodash[methodName],
|
||||||
|
checkIteratee = /(?:filter|map|reject|While)/.test(methodName),
|
||||||
retUnwrapped = /^(?:first|last)$/.test(methodName);
|
retUnwrapped = /^(?:first|last)$/.test(methodName);
|
||||||
|
|
||||||
lodash.prototype[methodName] = function() {
|
lodash.prototype[methodName] = function() {
|
||||||
@@ -11594,9 +11595,14 @@
|
|||||||
args = arguments,
|
args = arguments,
|
||||||
chainAll = this.__chain__,
|
chainAll = this.__chain__,
|
||||||
isHybrid = !!this.__actions__.length,
|
isHybrid = !!this.__actions__.length,
|
||||||
isLazy = value instanceof LazyWrapper,
|
isLazy = value instanceof LazyWrapper;
|
||||||
onlyLazy = isLazy && !isHybrid;
|
|
||||||
|
|
||||||
|
if (isLazy && checkIteratee) {
|
||||||
|
// avoid lazy use if the iteratee has a `length` other than `1`
|
||||||
|
var iteratee = args[0];
|
||||||
|
isLazy = !(typeof iteratee == 'function' && iteratee.length != 1);
|
||||||
|
}
|
||||||
|
var onlyLazy = isLazy && !isHybrid;
|
||||||
if (retUnwrapped && !chainAll) {
|
if (retUnwrapped && !chainAll) {
|
||||||
return onlyLazy
|
return onlyLazy
|
||||||
? func.call(value)
|
? func.call(value)
|
||||||
|
|||||||
218
test/test.js
218
test/test.js
@@ -3973,18 +3973,37 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should provide the correct `predicate` arguments in a lazy chain sequence', 1, function() {
|
test('should provide the correct `predicate` arguments in a lazy chain sequence', 4, function() {
|
||||||
if (!isNpm) {
|
if (!isNpm) {
|
||||||
var args;
|
var args,
|
||||||
|
expected = [16, 3, [1, 4, 9 ,16]];
|
||||||
|
|
||||||
|
_(array).map(square).dropRightWhile(function(value, index, array) {
|
||||||
|
args = slice.call(arguments);
|
||||||
|
}).value();
|
||||||
|
|
||||||
|
deepEqual(args, expected);
|
||||||
|
|
||||||
|
_(array).map(square).dropRightWhile(function(value, index) {
|
||||||
|
args = slice.call(arguments);
|
||||||
|
}).value();
|
||||||
|
|
||||||
|
deepEqual(args, expected);
|
||||||
|
|
||||||
|
_(array).map(square).dropRightWhile(function(value) {
|
||||||
|
args = slice.call(arguments);
|
||||||
|
}).value();
|
||||||
|
|
||||||
|
deepEqual(args, [16, 3, array]);
|
||||||
|
|
||||||
_(array).map(square).dropRightWhile(function() {
|
_(array).map(square).dropRightWhile(function() {
|
||||||
args = slice.call(arguments);
|
args = slice.call(arguments);
|
||||||
}).value();
|
}).value();
|
||||||
|
|
||||||
deepEqual(args, [16, 3, array]);
|
deepEqual(args, expected);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
skipTest(1);
|
skipTest(4);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}());
|
}());
|
||||||
@@ -4055,18 +4074,37 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should provide the correct `predicate` arguments in a lazy chain sequence', 1, function() {
|
test('should provide the correct `predicate` arguments in a lazy chain sequence', 4, function() {
|
||||||
if (!isNpm) {
|
if (!isNpm) {
|
||||||
var args;
|
var args,
|
||||||
|
expected = [1, 0, [1, 4, 9, 16]];
|
||||||
|
|
||||||
|
_(array).map(square).dropWhile(function(value, index, array) {
|
||||||
|
args = slice.call(arguments);
|
||||||
|
}).value();
|
||||||
|
|
||||||
|
deepEqual(args, expected);
|
||||||
|
|
||||||
|
_(array).map(square).dropWhile(function(value, index) {
|
||||||
|
args = slice.call(arguments);
|
||||||
|
}).value();
|
||||||
|
|
||||||
|
deepEqual(args, expected);
|
||||||
|
|
||||||
|
_(array).map(square).dropWhile(function(index) {
|
||||||
|
args = slice.call(arguments);
|
||||||
|
}).value();
|
||||||
|
|
||||||
|
deepEqual(args, [1, 0, array]);
|
||||||
|
|
||||||
_(array).map(square).dropWhile(function() {
|
_(array).map(square).dropWhile(function() {
|
||||||
args = slice.call(arguments);
|
args = slice.call(arguments);
|
||||||
}).value();
|
}).value();
|
||||||
|
|
||||||
deepEqual(args, [1, 0, array]);
|
deepEqual(args, expected);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
skipTest(1);
|
skipTest(4);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}());
|
}());
|
||||||
@@ -4855,32 +4893,52 @@
|
|||||||
deepEqual(_.takeRightWhile(objects, 'b'), objects.slice(1));
|
deepEqual(_.takeRightWhile(objects, 'b'), objects.slice(1));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should return a wrapped value when chaining', 2, function() {
|
test('should work in a lazy chain sequence', 3, function() {
|
||||||
if (!isNpm) {
|
if (!isNpm) {
|
||||||
var wrapped = _(array).takeRightWhile(function(num) {
|
var wrapped = _(array).takeRightWhile(function(num) {
|
||||||
return num > 2;
|
return num > 2;
|
||||||
});
|
});
|
||||||
|
|
||||||
ok(wrapped instanceof _);
|
|
||||||
deepEqual(wrapped.value(), [3, 4]);
|
deepEqual(wrapped.value(), [3, 4]);
|
||||||
|
deepEqual(wrapped.reverse().value(), [4, 3]);
|
||||||
|
strictEqual(wrapped.last(), 4);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
skipTest(2);
|
skipTest(3);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should provide the correct `predicate` arguments in a lazy chain sequence', 1, function() {
|
test('should provide the correct `predicate` arguments in a lazy chain sequence', 4, function() {
|
||||||
if (!isNpm) {
|
if (!isNpm) {
|
||||||
var args;
|
var args,
|
||||||
|
expected = [16, 3, [1, 4, 9 , 16]];
|
||||||
|
|
||||||
|
_(array).map(square).takeRightWhile(function(value, index, array) {
|
||||||
|
args = slice.call(arguments)
|
||||||
|
}).value();
|
||||||
|
|
||||||
|
deepEqual(args, expected);
|
||||||
|
|
||||||
|
_(array).map(square).takeRightWhile(function(value, index) {
|
||||||
|
args = slice.call(arguments)
|
||||||
|
}).value();
|
||||||
|
|
||||||
|
deepEqual(args, expected);
|
||||||
|
|
||||||
|
_(array).map(square).takeRightWhile(function(index) {
|
||||||
|
args = slice.call(arguments);
|
||||||
|
}).value();
|
||||||
|
|
||||||
|
deepEqual(args, [16, 3, array]);
|
||||||
|
|
||||||
_(array).map(square).takeRightWhile(function() {
|
_(array).map(square).takeRightWhile(function() {
|
||||||
args = slice.call(arguments);
|
args = slice.call(arguments);
|
||||||
}).value();
|
}).value();
|
||||||
|
|
||||||
deepEqual(args, [16, 3, array]);
|
deepEqual(args, expected);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
skipTest(1);
|
skipTest(4);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}());
|
}());
|
||||||
@@ -4950,18 +5008,37 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should provide the correct `predicate` arguments in a lazy chain sequence', 1, function() {
|
test('should provide the correct `predicate` arguments in a lazy chain sequence', 4, function() {
|
||||||
if (!isNpm) {
|
if (!isNpm) {
|
||||||
var args;
|
var args,
|
||||||
|
expected = [1, 0, [1, 4, 9, 16]];
|
||||||
|
|
||||||
|
_(array).map(square).takeWhile(function(value, index, array) {
|
||||||
|
args = slice.call(arguments);
|
||||||
|
}).value();
|
||||||
|
|
||||||
|
deepEqual(args, expected);
|
||||||
|
|
||||||
|
_(array).map(square).takeWhile(function(value, index) {
|
||||||
|
args = slice.call(arguments);
|
||||||
|
}).value();
|
||||||
|
|
||||||
|
deepEqual(args, expected);
|
||||||
|
|
||||||
|
_(array).map(square).takeWhile(function(value) {
|
||||||
|
args = slice.call(arguments);
|
||||||
|
}).value();
|
||||||
|
|
||||||
|
deepEqual(args, [1, 0, array]);
|
||||||
|
|
||||||
_(array).map(square).takeWhile(function() {
|
_(array).map(square).takeWhile(function() {
|
||||||
args = slice.call(arguments);
|
args = slice.call(arguments);
|
||||||
}).value();
|
}).value();
|
||||||
|
|
||||||
deepEqual(args, [1, 0, array]);
|
deepEqual(args, expected);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
skipTest(1);
|
skipTest(4);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}());
|
}());
|
||||||
@@ -5934,7 +6011,7 @@
|
|||||||
if (!isNpm) {
|
if (!isNpm) {
|
||||||
var array = [1, 2, 1, 3],
|
var array = [1, 2, 1, 3],
|
||||||
iteratee = function(value) { value.push(value[0]); return value; },
|
iteratee = function(value) { value.push(value[0]); return value; },
|
||||||
predicate = function(value, index) { return index; },
|
predicate = function(value) { return value[0] > 1; },
|
||||||
actual = _(array).groupBy(_.identity).map(iteratee).filter(predicate).take().value();
|
actual = _(array).groupBy(_.identity).map(iteratee).filter(predicate).take().value();
|
||||||
|
|
||||||
deepEqual(actual, [[2, 2]]);
|
deepEqual(actual, [[2, 2]]);
|
||||||
@@ -9099,6 +9176,43 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should provide the correct `predicate` arguments in a lazy chain sequence', 4, function() {
|
||||||
|
if (!isNpm) {
|
||||||
|
var args,
|
||||||
|
expected = [1, 0, [1, 4, 9]];
|
||||||
|
|
||||||
|
_(array).map(square).map(function(value, index, array) {
|
||||||
|
args || (args = slice.call(arguments));
|
||||||
|
}).value();
|
||||||
|
|
||||||
|
deepEqual(args, expected);
|
||||||
|
|
||||||
|
args = null;
|
||||||
|
_(array).map(square).map(function(value, index) {
|
||||||
|
args || (args = slice.call(arguments));
|
||||||
|
}).value();
|
||||||
|
|
||||||
|
deepEqual(args, expected);
|
||||||
|
|
||||||
|
args = null;
|
||||||
|
_(array).map(square).map(function(value) {
|
||||||
|
args || (args = slice.call(arguments));
|
||||||
|
}).value();
|
||||||
|
|
||||||
|
deepEqual(args, [1, 0, array]);
|
||||||
|
|
||||||
|
args = null;
|
||||||
|
_(array).map(square).map(function() {
|
||||||
|
args || (args = slice.call(arguments));
|
||||||
|
}).value();
|
||||||
|
|
||||||
|
deepEqual(args, expected);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
skipTest(4);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test('should be aliased', 1, function() {
|
test('should be aliased', 1, function() {
|
||||||
strictEqual(_.collect, _.map);
|
strictEqual(_.collect, _.map);
|
||||||
});
|
});
|
||||||
@@ -10307,10 +10421,11 @@
|
|||||||
|
|
||||||
test('should produce methods that work in a lazy chain sequence', 1, function() {
|
test('should produce methods that work in a lazy chain sequence', 1, function() {
|
||||||
if (!isNpm) {
|
if (!isNpm) {
|
||||||
var predicate = function(value) { return value > 2; };
|
|
||||||
_.mixin({ 'a': _.countBy, 'b': _.filter });
|
_.mixin({ 'a': _.countBy, 'b': _.filter });
|
||||||
|
|
||||||
var actual = _([1, 2, 1, 3]).a(_.identity).map(square).b(predicate).take().value();
|
var predicate = function(value) { return value > 2; },
|
||||||
|
actual = _([1, 2, 1, 3]).a(_.identity).map(square).b(predicate).take().value();
|
||||||
|
|
||||||
deepEqual(actual, [4]);
|
deepEqual(actual, [4]);
|
||||||
|
|
||||||
delete _.a;
|
delete _.a;
|
||||||
@@ -11987,8 +12102,10 @@
|
|||||||
QUnit.module('filter methods');
|
QUnit.module('filter methods');
|
||||||
|
|
||||||
_.each(['filter', 'reject'], function(methodName) {
|
_.each(['filter', 'reject'], function(methodName) {
|
||||||
var func = _[methodName],
|
var array = [1, 2, 3, 4],
|
||||||
isFilter = methodName == 'filter';
|
func = _[methodName],
|
||||||
|
isFilter = methodName == 'filter',
|
||||||
|
objects = [{ 'a': 0 }, { 'a': 1 }];
|
||||||
|
|
||||||
test('`_.' + methodName + '` should not modify the resulting value from within `predicate`', 1, function() {
|
test('`_.' + methodName + '` should not modify the resulting value from within `predicate`', 1, function() {
|
||||||
var actual = func([0], function(num, index, array) {
|
var actual = func([0], function(num, index, array) {
|
||||||
@@ -12000,18 +12117,16 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('`_.' + methodName + '` should work with a "_.property" style `predicate`', 1, function() {
|
test('`_.' + methodName + '` should work with a "_.property" style `predicate`', 1, function() {
|
||||||
var objects = [{ 'a': 0 }, { 'a': 1 }];
|
|
||||||
deepEqual(func(objects, 'a'), [objects[isFilter ? 1 : 0]]);
|
deepEqual(func(objects, 'a'), [objects[isFilter ? 1 : 0]]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('`_.' + methodName + '` should work with a "_where" style `predicate`', 1, function() {
|
test('`_.' + methodName + '` should work with a "_where" style `predicate`', 1, function() {
|
||||||
var objects = [{ 'a': 0 }, { 'a': 1 }];
|
|
||||||
deepEqual(func(objects, objects[1]), [objects[isFilter ? 1 : 0]]);
|
deepEqual(func(objects, objects[1]), [objects[isFilter ? 1 : 0]]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('`_.' + methodName + '` should not modify wrapped values', 2, function() {
|
test('`_.' + methodName + '` should not modify wrapped values', 2, function() {
|
||||||
if (!isNpm) {
|
if (!isNpm) {
|
||||||
var wrapped = _([1, 2, 3, 4]);
|
var wrapped = _(array);
|
||||||
|
|
||||||
var actual = wrapped[methodName](function(num) {
|
var actual = wrapped[methodName](function(num) {
|
||||||
return num < 3;
|
return num < 3;
|
||||||
@@ -12032,23 +12147,58 @@
|
|||||||
|
|
||||||
test('`_.' + methodName + '` should work in a lazy chain sequence', 2, function() {
|
test('`_.' + methodName + '` should work in a lazy chain sequence', 2, function() {
|
||||||
if (!isNpm) {
|
if (!isNpm) {
|
||||||
var array = [1, 2, 3],
|
var object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
|
||||||
object = { 'a': 1, 'b': 2, 'c': 3 },
|
predicate = function(value) { return isFilter ? (value > 6) : (value < 6); };
|
||||||
doubled = function(value) { return value * 2; },
|
|
||||||
predicate = function(value) { return isFilter ? (value > 3) : (value < 3); };
|
|
||||||
|
|
||||||
var expected = [4, 6],
|
var expected = [9, 16],
|
||||||
actual = _(array).map(doubled)[methodName](predicate).value();
|
actual = _(array).map(square)[methodName](predicate).value();
|
||||||
|
|
||||||
deepEqual(actual, expected);
|
deepEqual(actual, expected);
|
||||||
|
|
||||||
actual = _(object).mapValues(doubled)[methodName](predicate).value();
|
actual = _(object).mapValues(square)[methodName](predicate).value();
|
||||||
deepEqual(actual, expected);
|
deepEqual(actual, expected);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
skipTest(2);
|
skipTest(2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('`_.' + methodName + '` should provide the correct `predicate` arguments in a lazy chain sequence', 4, function() {
|
||||||
|
if (!isNpm) {
|
||||||
|
var args,
|
||||||
|
expected = [1, 0, [1, 4, 9, 16]];
|
||||||
|
|
||||||
|
_(array).map(square)[methodName](function(value, index, array) {
|
||||||
|
args || (args = slice.call(arguments));
|
||||||
|
}).value();
|
||||||
|
|
||||||
|
deepEqual(args, expected);
|
||||||
|
|
||||||
|
args = null;
|
||||||
|
_(array).map(square)[methodName](function(value, index) {
|
||||||
|
args || (args = slice.call(arguments));
|
||||||
|
}).value();
|
||||||
|
|
||||||
|
deepEqual(args, expected);
|
||||||
|
|
||||||
|
args = null;
|
||||||
|
_(array).map(square)[methodName](function(value) {
|
||||||
|
args || (args = slice.call(arguments));
|
||||||
|
}).value();
|
||||||
|
|
||||||
|
deepEqual(args, [1, 0, array]);
|
||||||
|
|
||||||
|
args = null;
|
||||||
|
_(array).map(square)[methodName](function() {
|
||||||
|
args || (args = slice.call(arguments));
|
||||||
|
}).value();
|
||||||
|
|
||||||
|
deepEqual(args, expected);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
skipTest(4);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|||||||
Reference in New Issue
Block a user