mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-12 20:07:49 +00:00
Optimize _.max and _.min when invoked with iteratees and add _.gt, _.gte, _.lt, _.lte, & _.eq.
This commit is contained in:
258
lodash.src.js
258
lodash.src.js
@@ -923,30 +923,31 @@
|
|||||||
* `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, `forEach`,
|
* `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, `forEach`,
|
||||||
* `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `functions`,
|
* `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `functions`,
|
||||||
* `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, `invoke`, `keys`,
|
* `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, `invoke`, `keys`,
|
||||||
* `keysIn`, `map`, `mapValues`, `matches`, `matchesProperty`, `memoize`,
|
* `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
|
||||||
* `merge`, `mixin`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`,
|
* `memoize`, `merge`, `method`, `methodOf`, `mixin`, `negate`, `omit`, `once`,
|
||||||
* `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`,
|
* `pairs`, `partial`, `partialRight`, `partition`, `pick`, `plant`, `pluck`,
|
||||||
* `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `reverse`,
|
* `property`, `propertyOf`, `pull`, `pullAt`, `push`, `range`, `rearg`,
|
||||||
* `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, `sortByOrder`, `splice`,
|
* `reject`, `remove`, `rest`, `restParam`, `reverse`, `set`, `shuffle`,
|
||||||
* `spread`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`,
|
* `slice`, `sort`, `sortBy`, `sortByAll`, `sortByOrder`, `splice`, `spread`,
|
||||||
* `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, `transform`,
|
* `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`,
|
||||||
* `union`, `uniq`, `unshift`, `unzip`, `values`, `valuesIn`, `where`,
|
* `thru`, `times`, `toArray`, `toPlainObject`, `transform`, `union`, `uniq`,
|
||||||
* `without`, `wrap`, `xor`, `zip`, and `zipObject`
|
* `unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`, `where`, `without`,
|
||||||
|
* `wrap`, `xor`, `zip`, `zipObject`, `zipWith`
|
||||||
*
|
*
|
||||||
* The wrapper methods that are **not** chainable by default are:
|
* The wrapper methods that are **not** chainable by default are:
|
||||||
* `add`, `attempt`, `camelCase`, `capitalize`, `clone`, `cloneDeep`, `deburr`,
|
* `add`, `attempt`, `camelCase`, `capitalize`, `clone`, `cloneDeep`, `deburr`,
|
||||||
* `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`,
|
* `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`,
|
||||||
* `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `has`,
|
* `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `get`,
|
||||||
* `identity`, `includes`, `indexOf`, `inRange`, `isArguments`, `isArray`,
|
* `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, `inRange`, `isArguments`,
|
||||||
* `isBoolean`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isError`, `isFinite`
|
* `isArray`, `isBoolean`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isError`,
|
||||||
* `isFunction`, `isMatch`, `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`,
|
* `isFinite` `isFunction`, `isMatch`, `isNative`, `isNaN`, `isNull`, `isNumber`,
|
||||||
* `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `isTypedArray`,
|
* `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`,
|
||||||
* `join`, `kebabCase`, `last`, `lastIndexOf`, `max`, `min`, `noConflict`,
|
* `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `lt`, `lte`,
|
||||||
* `noop`, `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`,
|
* `max`, `min`, `noConflict`, `noop`, `now`, `pad`, `padLeft`, `padRight`,
|
||||||
* `reduce`, `reduceRight`, `repeat`, `result`, `runInContext`, `shift`, `size`,
|
* `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`,
|
||||||
* `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, `startsWith`,
|
* `runInContext`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`,
|
||||||
* `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, `unescape`,
|
* `sortedLastIndex`, `startCase`, `startsWith`, `sum`, `template`, `trim`,
|
||||||
* `uniqueId`, `value`, and `words`
|
* `trimLeft`, `trimRight`, `trunc`, `unescape`, `uniqueId`, `value`, and `words`
|
||||||
*
|
*
|
||||||
* The wrapper method `sample` will return a wrapped value when `n` is provided,
|
* The wrapper method `sample` will return a wrapped value when `n` is provided,
|
||||||
* otherwise an unwrapped value is returned.
|
* otherwise an unwrapped value is returned.
|
||||||
@@ -1568,6 +1569,35 @@
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A specialized version of `baseExtremum` for arrays whichs invokes `iteratee`
|
||||||
|
* with one argument: (value).
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Array} array The array to iterate over.
|
||||||
|
* @param {Function} iteratee The function invoked per iteration.
|
||||||
|
* @param {Function} comparator The function used to compare values.
|
||||||
|
* @param {*} exValue The initial extremum value.
|
||||||
|
* @returns {*} Returns the extremum value.
|
||||||
|
*/
|
||||||
|
function arrayExtremum(array, iteratee, comparator, exValue) {
|
||||||
|
var index = -1,
|
||||||
|
length = array.length,
|
||||||
|
computed = exValue,
|
||||||
|
result = computed;
|
||||||
|
|
||||||
|
while (++index < length) {
|
||||||
|
var value = array[index],
|
||||||
|
current = +iteratee(value);
|
||||||
|
|
||||||
|
if (comparator(current, computed)) {
|
||||||
|
computed = current;
|
||||||
|
result = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A specialized version of `_.filter` for arrays without support for callback
|
* A specialized version of `_.filter` for arrays without support for callback
|
||||||
* shorthands and `this` binding.
|
* shorthands and `this` binding.
|
||||||
@@ -1612,48 +1642,6 @@
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A specialized version of `_.max` for arrays without support for iteratees.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Array} array The array to iterate over.
|
|
||||||
* @returns {*} Returns the maximum value.
|
|
||||||
*/
|
|
||||||
function arrayMax(array) {
|
|
||||||
var index = -1,
|
|
||||||
length = array.length,
|
|
||||||
result = NEGATIVE_INFINITY;
|
|
||||||
|
|
||||||
while (++index < length) {
|
|
||||||
var value = array[index];
|
|
||||||
if (value > result) {
|
|
||||||
result = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A specialized version of `_.min` for arrays without support for iteratees.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Array} array The array to iterate over.
|
|
||||||
* @returns {*} Returns the minimum value.
|
|
||||||
*/
|
|
||||||
function arrayMin(array) {
|
|
||||||
var index = -1,
|
|
||||||
length = array.length,
|
|
||||||
result = POSITIVE_INFINITY;
|
|
||||||
|
|
||||||
while (++index < length) {
|
|
||||||
var value = array[index];
|
|
||||||
if (value < result) {
|
|
||||||
result = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A specialized version of `_.reduce` for arrays without support for callback
|
* A specialized version of `_.reduce` for arrays without support for callback
|
||||||
* shorthands and `this` binding.
|
* shorthands and `this` binding.
|
||||||
@@ -2091,6 +2079,32 @@
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the extremum value of `collection` invoking `iteratee` for each value
|
||||||
|
* in `collection` to generate the criterion by which the value is ranked.
|
||||||
|
* The `iteratee` is invoked with three arguments: (value, index|key, collection).
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {Array|Object|string} collection The collection to iterate over.
|
||||||
|
* @param {Function} iteratee The function invoked per iteration.
|
||||||
|
* @param {Function} comparator The function used to compare values.
|
||||||
|
* @param {*} exValue The initial extremum value.
|
||||||
|
* @returns {*} Returns the extremum value.
|
||||||
|
*/
|
||||||
|
function baseExtremum(collection, iteratee, comparator, exValue) {
|
||||||
|
var computed = exValue,
|
||||||
|
result = computed;
|
||||||
|
|
||||||
|
baseEach(collection, function(value, index, collection) {
|
||||||
|
var current = +iteratee(value, index, collection);
|
||||||
|
if (comparator(current, computed) || (current === exValue && current === result)) {
|
||||||
|
computed = current;
|
||||||
|
result = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base implementation of `_.fill` without an iteratee call guard.
|
* The base implementation of `_.fill` without an iteratee call guard.
|
||||||
*
|
*
|
||||||
@@ -3427,27 +3441,26 @@
|
|||||||
* extremum value.
|
* extremum value.
|
||||||
* @returns {Function} Returns the new extremum function.
|
* @returns {Function} Returns the new extremum function.
|
||||||
*/
|
*/
|
||||||
function createExtremum(arrayFunc, isMin) {
|
function createExtremum(comparator, exValue) {
|
||||||
return function(collection, iteratee, thisArg) {
|
return function(collection, iteratee, thisArg) {
|
||||||
if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
|
if (thisArg && isIterateeCall(collection, iteratee, thisArg)) {
|
||||||
iteratee = null;
|
iteratee = null;
|
||||||
}
|
}
|
||||||
var callback = getCallback(),
|
var callback = getCallback(),
|
||||||
noIteratee = iteratee == null;
|
noIteratee = iteratee == null,
|
||||||
|
isArr = isArray(collection);
|
||||||
|
|
||||||
if (!(noIteratee && callback === baseCallback)) {
|
iteratee = (noIteratee && callback === baseCallback && !isArr && isString(collection))
|
||||||
noIteratee = false;
|
? charAtCallback
|
||||||
iteratee = callback(iteratee, thisArg, 3);
|
: callback(iteratee, thisArg, 3);
|
||||||
}
|
|
||||||
if (noIteratee) {
|
if (noIteratee || (isArr && iteratee.length == 1)) {
|
||||||
var isArr = isArray(collection);
|
var result = arrayExtremum(isArr ? collection : toIterable(collection), iteratee, comparator, exValue);
|
||||||
if (!isArr && isString(collection)) {
|
if (noIteratee || !(length && result === exValue)) {
|
||||||
iteratee = charAtCallback;
|
return result;
|
||||||
} else {
|
|
||||||
return arrayFunc(isArr ? collection : toIterable(collection));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return extremumBy(collection, iteratee, isMin);
|
return baseExtremum(collection, iteratee, comparator, exValue);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4045,34 +4058,6 @@
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the extremum value of `collection` invoking `iteratee` for each value
|
|
||||||
* in `collection` to generate the criterion by which the value is ranked.
|
|
||||||
* The `iteratee` is invoked with three arguments: (value, index, collection).
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {Array|Object|string} collection The collection to iterate over.
|
|
||||||
* @param {Function} iteratee The function invoked per iteration.
|
|
||||||
* @param {boolean} [isMin] Specify returning the minimum, instead of the
|
|
||||||
* maximum, extremum value.
|
|
||||||
* @returns {*} Returns the extremum value.
|
|
||||||
*/
|
|
||||||
function extremumBy(collection, iteratee, isMin) {
|
|
||||||
var exValue = isMin ? POSITIVE_INFINITY : NEGATIVE_INFINITY,
|
|
||||||
computed = exValue,
|
|
||||||
result = computed;
|
|
||||||
|
|
||||||
baseEach(collection, function(value, index, collection) {
|
|
||||||
var current = iteratee(value, index, collection);
|
|
||||||
if ((isMin ? (current < computed) : (current > computed)) ||
|
|
||||||
(current === exValue && current === result)) {
|
|
||||||
computed = current;
|
|
||||||
result = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the appropriate "callback" function. If the `_.callback` method is
|
* Gets the appropriate "callback" function. If the `_.callback` method is
|
||||||
* customized this function returns the custom method, otherwise it returns
|
* customized this function returns the custom method, otherwise it returns
|
||||||
@@ -8609,6 +8594,35 @@
|
|||||||
: baseClone(value, true);
|
: baseClone(value, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if `value` is greater than `other`.
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @memberOf _
|
||||||
|
* @category Lang
|
||||||
|
* @param {*} value The value to compare.
|
||||||
|
* @param {*} other The other value to compare.
|
||||||
|
* @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`.
|
||||||
|
*/
|
||||||
|
function gt(value, other) {
|
||||||
|
return value > other;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if `value` is greater than or equal to `other`.
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @memberOf _
|
||||||
|
* @category Lang
|
||||||
|
* @param {*} value The value to compare.
|
||||||
|
* @param {*} other The other value to compare.
|
||||||
|
* @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`.
|
||||||
|
*/
|
||||||
|
function gte(value, other) {
|
||||||
|
return value >= other;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if `value` is classified as an `arguments` object.
|
* Checks if `value` is classified as an `arguments` object.
|
||||||
*
|
*
|
||||||
@@ -8776,6 +8790,7 @@
|
|||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
* @memberOf _
|
* @memberOf _
|
||||||
|
* @alias eq
|
||||||
* @category Lang
|
* @category Lang
|
||||||
* @param {*} value The value to compare.
|
* @param {*} value The value to compare.
|
||||||
* @param {*} other The other value to compare.
|
* @param {*} other The other value to compare.
|
||||||
@@ -9209,6 +9224,34 @@
|
|||||||
return value === undefined;
|
return value === undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if `value` is less than `other`.
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @memberOf _
|
||||||
|
* @category Lang
|
||||||
|
* @param {*} value The value to compare.
|
||||||
|
* @param {*} other The other value to compare.
|
||||||
|
* @returns {boolean} Returns `true` if `value` is less than `other`, else `false`.
|
||||||
|
*/
|
||||||
|
function lt(value, other) {
|
||||||
|
return value < other;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if `value` is less than or equal to `other`.
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @memberOf _
|
||||||
|
* @category Lang
|
||||||
|
* @param {*} value The value to compare.
|
||||||
|
* @param {*} other The other value to compare.
|
||||||
|
* @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`.
|
||||||
|
*/
|
||||||
|
function lte(value, other) {
|
||||||
|
return value <= other;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts `value` to an array.
|
* Converts `value` to an array.
|
||||||
*
|
*
|
||||||
@@ -11822,7 +11865,7 @@
|
|||||||
* _.max(users, 'age');
|
* _.max(users, 'age');
|
||||||
* // => { 'user': 'fred', 'age': 40 }
|
* // => { 'user': 'fred', 'age': 40 }
|
||||||
*/
|
*/
|
||||||
var max = createExtremum(arrayMax);
|
var max = createExtremum(gt, -Infinity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the minimum value of `collection`. If `collection` is empty or falsey
|
* Gets the minimum value of `collection`. If `collection` is empty or falsey
|
||||||
@@ -11871,7 +11914,7 @@
|
|||||||
* _.min(users, 'age');
|
* _.min(users, 'age');
|
||||||
* // => { 'user': 'barney', 'age': 36 }
|
* // => { 'user': 'barney', 'age': 36 }
|
||||||
*/
|
*/
|
||||||
var min = createExtremum(arrayMin, true);
|
var min = createExtremum(lt, Infinity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the sum of the values in `collection`.
|
* Gets the sum of the values in `collection`.
|
||||||
@@ -12093,6 +12136,8 @@
|
|||||||
lodash.findWhere = findWhere;
|
lodash.findWhere = findWhere;
|
||||||
lodash.first = first;
|
lodash.first = first;
|
||||||
lodash.get = get;
|
lodash.get = get;
|
||||||
|
lodash.gt = gt;
|
||||||
|
lodash.gte = gte;
|
||||||
lodash.has = has;
|
lodash.has = has;
|
||||||
lodash.identity = identity;
|
lodash.identity = identity;
|
||||||
lodash.includes = includes;
|
lodash.includes = includes;
|
||||||
@@ -12122,6 +12167,8 @@
|
|||||||
lodash.kebabCase = kebabCase;
|
lodash.kebabCase = kebabCase;
|
||||||
lodash.last = last;
|
lodash.last = last;
|
||||||
lodash.lastIndexOf = lastIndexOf;
|
lodash.lastIndexOf = lastIndexOf;
|
||||||
|
lodash.lt = lt;
|
||||||
|
lodash.lte = lte;
|
||||||
lodash.max = max;
|
lodash.max = max;
|
||||||
lodash.min = min;
|
lodash.min = min;
|
||||||
lodash.noConflict = noConflict;
|
lodash.noConflict = noConflict;
|
||||||
@@ -12158,6 +12205,7 @@
|
|||||||
lodash.all = every;
|
lodash.all = every;
|
||||||
lodash.any = some;
|
lodash.any = some;
|
||||||
lodash.contains = includes;
|
lodash.contains = includes;
|
||||||
|
lodash.eq = isEqual;
|
||||||
lodash.detect = find;
|
lodash.detect = find;
|
||||||
lodash.foldl = reduce;
|
lodash.foldl = reduce;
|
||||||
lodash.foldr = reduceRight;
|
lodash.foldr = reduceRight;
|
||||||
|
|||||||
@@ -17816,7 +17816,7 @@
|
|||||||
|
|
||||||
var acceptFalsey = _.difference(allMethods, rejectFalsey);
|
var acceptFalsey = _.difference(allMethods, rejectFalsey);
|
||||||
|
|
||||||
test('should accept falsey arguments', 220, function() {
|
test('should accept falsey arguments', 225, function() {
|
||||||
var emptyArrays = _.map(falsey, _.constant([])),
|
var emptyArrays = _.map(falsey, _.constant([])),
|
||||||
isExposed = '_' in root,
|
isExposed = '_' in root,
|
||||||
oldDash = root._;
|
oldDash = root._;
|
||||||
@@ -17982,8 +17982,9 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should not contain minified method names (test production builds)', 1, function() {
|
test('should not contain minified method names (test production builds)', 1, function() {
|
||||||
|
var shortNames = ['at', 'eq', 'gt', 'lt'];
|
||||||
ok(_.every(_.functions(_), function(methodName) {
|
ok(_.every(_.functions(_), function(methodName) {
|
||||||
return methodName.length > 2 || methodName === 'at';
|
return methodName.length > 2 || _.includes(shortNames, methodName);
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
}());
|
}());
|
||||||
|
|||||||
Reference in New Issue
Block a user