mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-01 15:57:48 +00:00
Add baseGt, baseLt, baseToNumber, baseToString, and createRelationalOperation.
This commit is contained in:
411
lodash.js
411
lodash.js
@@ -710,35 +710,6 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base implementation of methods like `_.max` and `_.min` which accepts a
|
||||
* `comparator` to determine the extremum value.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to iterate over.
|
||||
* @param {Function} iteratee The iteratee invoked per iteration.
|
||||
* @param {Function} comparator The comparator used to compare values.
|
||||
* @returns {*} Returns the extremum value.
|
||||
*/
|
||||
function baseExtremum(array, iteratee, comparator) {
|
||||
var index = -1,
|
||||
length = array.length;
|
||||
|
||||
while (++index < length) {
|
||||
var value = array[index],
|
||||
current = iteratee(value);
|
||||
|
||||
if (current != null && (computed === undefined
|
||||
? current === current
|
||||
: comparator(current, computed)
|
||||
)) {
|
||||
var computed = current,
|
||||
result = value;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base implementation of methods like `_.find` and `_.findKey`, without
|
||||
* support for iteratee shorthands, which iterates over `collection` using
|
||||
@@ -1017,79 +988,6 @@
|
||||
return (value && value.Object === Object) ? value : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares values to sort them in ascending order.
|
||||
*
|
||||
* @private
|
||||
* @param {*} value The value to compare.
|
||||
* @param {*} other The other value to compare.
|
||||
* @returns {number} Returns the sort order indicator for `value`.
|
||||
*/
|
||||
function compareAscending(value, other) {
|
||||
if (value !== other) {
|
||||
var valIsNull = value === null,
|
||||
valIsUndef = value === undefined,
|
||||
valIsReflexive = value === value;
|
||||
|
||||
var othIsNull = other === null,
|
||||
othIsUndef = other === undefined,
|
||||
othIsReflexive = other === other;
|
||||
|
||||
if ((value > other && !othIsNull) || !valIsReflexive ||
|
||||
(valIsNull && !othIsUndef && othIsReflexive) ||
|
||||
(valIsUndef && othIsReflexive)) {
|
||||
return 1;
|
||||
}
|
||||
if ((value < other && !valIsNull) || !othIsReflexive ||
|
||||
(othIsNull && !valIsUndef && valIsReflexive) ||
|
||||
(othIsUndef && valIsReflexive)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by `_.orderBy` to compare multiple properties of a value to another
|
||||
* and stable sort them.
|
||||
*
|
||||
* If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
|
||||
* specify an order of "desc" for descending or "asc" for ascending sort order
|
||||
* of corresponding values.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to compare.
|
||||
* @param {Object} other The other object to compare.
|
||||
* @param {boolean[]|string[]} orders The order to sort by for each property.
|
||||
* @returns {number} Returns the sort order indicator for `object`.
|
||||
*/
|
||||
function compareMultiple(object, other, orders) {
|
||||
var index = -1,
|
||||
objCriteria = object.criteria,
|
||||
othCriteria = other.criteria,
|
||||
length = objCriteria.length,
|
||||
ordersLength = orders.length;
|
||||
|
||||
while (++index < length) {
|
||||
var result = compareAscending(objCriteria[index], othCriteria[index]);
|
||||
if (result) {
|
||||
if (index >= ordersLength) {
|
||||
return result;
|
||||
}
|
||||
var order = orders[index];
|
||||
return result * (order == 'desc' ? -1 : 1);
|
||||
}
|
||||
}
|
||||
// Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
|
||||
// that causes it, under certain circumstances, to provide the same value for
|
||||
// `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
|
||||
// for more details.
|
||||
//
|
||||
// This also ensures a stable sort in V8 and other engines.
|
||||
// See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
|
||||
return object.index - other.index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of `placeholder` occurrences in `array`.
|
||||
*
|
||||
@@ -1110,29 +1008,6 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a function that performs a mathematical operation on two values.
|
||||
*
|
||||
* @private
|
||||
* @param {Function} operator The function to perform the operation.
|
||||
* @returns {Function} Returns the new mathematical operation function.
|
||||
*/
|
||||
function createMathOperation(operator) {
|
||||
return function(value, other) {
|
||||
var result;
|
||||
if (value === undefined && other === undefined) {
|
||||
return 0;
|
||||
}
|
||||
if (value !== undefined) {
|
||||
result = value;
|
||||
}
|
||||
if (other !== undefined) {
|
||||
result = result === undefined ? other : operator(result, other);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters.
|
||||
*
|
||||
@@ -2613,6 +2488,35 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base implementation of methods like `_.max` and `_.min` which accepts a
|
||||
* `comparator` to determine the extremum value.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} array The array to iterate over.
|
||||
* @param {Function} iteratee The iteratee invoked per iteration.
|
||||
* @param {Function} comparator The comparator used to compare values.
|
||||
* @returns {*} Returns the extremum value.
|
||||
*/
|
||||
function baseExtremum(array, iteratee, comparator) {
|
||||
var index = -1,
|
||||
length = array.length;
|
||||
|
||||
while (++index < length) {
|
||||
var value = array[index],
|
||||
current = iteratee(value);
|
||||
|
||||
if (current != null && (computed === undefined
|
||||
? (current === current && !isSymbol(current))
|
||||
: comparator(current, computed)
|
||||
)) {
|
||||
var computed = current,
|
||||
result = value;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base implementation of `_.fill` without an iteratee call guard.
|
||||
*
|
||||
@@ -2795,6 +2699,19 @@
|
||||
: arrayPush(result, symbolsFunc(object));
|
||||
}
|
||||
|
||||
/**
|
||||
* The base implementation of `_.gt` which doesn't coerce arguments to numbers.
|
||||
*
|
||||
* @private
|
||||
* @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 baseGt(value, other) {
|
||||
return value > other;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base implementation of `_.has` without support for deep paths.
|
||||
*
|
||||
@@ -3134,6 +3051,19 @@
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The base implementation of `_.lt` which doesn't coerce arguments to numbers.
|
||||
*
|
||||
* @private
|
||||
* @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 baseLt(value, other) {
|
||||
return value < other;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base implementation of `_.map` without support for iteratee shorthands.
|
||||
*
|
||||
@@ -3667,7 +3597,8 @@
|
||||
var mid = (low + high) >>> 1,
|
||||
computed = array[mid];
|
||||
|
||||
if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) {
|
||||
if (computed !== null && !isSymbol(computed) &&
|
||||
(retHighest ? (computed <= value) : (computed < value))) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
high = mid;
|
||||
@@ -3698,21 +3629,26 @@
|
||||
high = array ? array.length : 0,
|
||||
valIsNaN = value !== value,
|
||||
valIsNull = value === null,
|
||||
valIsUndef = value === undefined;
|
||||
valIsSymbol = isSymbol(value),
|
||||
valIsUndefined = value === undefined;
|
||||
|
||||
while (low < high) {
|
||||
var mid = nativeFloor((low + high) / 2),
|
||||
computed = iteratee(array[mid]),
|
||||
isDef = computed !== undefined,
|
||||
isReflexive = computed === computed;
|
||||
othIsDefined = computed !== undefined,
|
||||
othIsNull = computed === null,
|
||||
othIsReflexive = computed === computed,
|
||||
othIsSymbol = isSymbol(computed);
|
||||
|
||||
if (valIsNaN) {
|
||||
var setLow = isReflexive || retHighest;
|
||||
var setLow = retHighest || othIsReflexive;
|
||||
} else if (valIsUndefined) {
|
||||
setLow = othIsReflexive && (retHighest || othIsDefined);
|
||||
} else if (valIsNull) {
|
||||
setLow = isReflexive && isDef && (retHighest || computed != null);
|
||||
} else if (valIsUndef) {
|
||||
setLow = isReflexive && (retHighest || isDef);
|
||||
} else if (computed == null) {
|
||||
setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
|
||||
} else if (valIsSymbol) {
|
||||
setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
|
||||
} else if (othIsNull || othIsSymbol) {
|
||||
setLow = false;
|
||||
} else {
|
||||
setLow = retHighest ? (computed <= value) : (computed < value);
|
||||
@@ -3767,6 +3703,27 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
function baseToNumber(value) {
|
||||
if (typeof value == 'number') {
|
||||
return value;
|
||||
}
|
||||
if (isSymbol(value)) {
|
||||
return NAN;
|
||||
}
|
||||
return +value;
|
||||
}
|
||||
|
||||
function baseToString(value) {
|
||||
// Exit early for strings to avoid a performance hit in some environments.
|
||||
if (typeof value == 'string') {
|
||||
return value;
|
||||
}
|
||||
if (isSymbol(value)) {
|
||||
return symbolToString ? symbolToString.call(value) : '';
|
||||
}
|
||||
return (value + '');
|
||||
}
|
||||
|
||||
/**
|
||||
* The base implementation of `_.uniqBy` without support for iteratee shorthands.
|
||||
*
|
||||
@@ -4102,6 +4059,85 @@
|
||||
return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares values to sort them in ascending order.
|
||||
*
|
||||
* @private
|
||||
* @param {*} value The value to compare.
|
||||
* @param {*} other The other value to compare.
|
||||
* @returns {number} Returns the sort order indicator for `value`.
|
||||
*/
|
||||
function compareAscending(value, other) {
|
||||
if (value !== other) {
|
||||
var valIsNull = value === null,
|
||||
valIsUndef = value === undefined,
|
||||
valIsReflexive = value === value,
|
||||
valIsSymbol = isSymbol(value);
|
||||
|
||||
var othIsNull = other === null,
|
||||
othIsUndef = other === undefined,
|
||||
othIsReflexive = other === other,
|
||||
othIsSymbol = isSymbol(other);
|
||||
|
||||
if ((valIsSymbol && !othIsSymbol) ||
|
||||
(!othIsNull && !othIsSymbol && value > other) ||
|
||||
(valIsNull && !othIsUndef && othIsReflexive) ||
|
||||
(valIsUndef && othIsReflexive) ||
|
||||
!valIsReflexive) {
|
||||
return 1;
|
||||
}
|
||||
if ((othIsSymbol && !valIsSymbol) ||
|
||||
(!valIsNull && !valIsSymbol && value < other) ||
|
||||
(othIsNull && !valIsUndef && valIsReflexive) ||
|
||||
(othIsUndef && valIsReflexive) ||
|
||||
!othIsReflexive) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by `_.orderBy` to compare multiple properties of a value to another
|
||||
* and stable sort them.
|
||||
*
|
||||
* If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
|
||||
* specify an order of "desc" for descending or "asc" for ascending sort order
|
||||
* of corresponding values.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} object The object to compare.
|
||||
* @param {Object} other The other object to compare.
|
||||
* @param {boolean[]|string[]} orders The order to sort by for each property.
|
||||
* @returns {number} Returns the sort order indicator for `object`.
|
||||
*/
|
||||
function compareMultiple(object, other, orders) {
|
||||
var index = -1,
|
||||
objCriteria = object.criteria,
|
||||
othCriteria = other.criteria,
|
||||
length = objCriteria.length,
|
||||
ordersLength = orders.length;
|
||||
|
||||
while (++index < length) {
|
||||
var result = compareAscending(objCriteria[index], othCriteria[index]);
|
||||
if (result) {
|
||||
if (index >= ordersLength) {
|
||||
return result;
|
||||
}
|
||||
var order = orders[index];
|
||||
return result * (order == 'desc' ? -1 : 1);
|
||||
}
|
||||
}
|
||||
// Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
|
||||
// that causes it, under certain circumstances, to provide the same value for
|
||||
// `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
|
||||
// for more details.
|
||||
//
|
||||
// This also ensures a stable sort in V8 and other engines.
|
||||
// See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
|
||||
return object.index - other.index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array that is the composition of partially applied arguments,
|
||||
* placeholders, and provided arguments into a single array of arguments.
|
||||
@@ -4621,6 +4657,39 @@
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a function that performs a mathematical operation on two values.
|
||||
*
|
||||
* @private
|
||||
* @param {Function} operator The function to perform the operation.
|
||||
* @returns {Function} Returns the new mathematical operation function.
|
||||
*/
|
||||
function createMathOperation(operator) {
|
||||
return function(value, other) {
|
||||
var result;
|
||||
if (value === undefined && other === undefined) {
|
||||
return 0;
|
||||
}
|
||||
if (value !== undefined) {
|
||||
result = value;
|
||||
}
|
||||
if (other !== undefined) {
|
||||
if (result === undefined) {
|
||||
return other;
|
||||
}
|
||||
if (typeof value == 'string' || typeof other == 'string') {
|
||||
value = baseToString(value);
|
||||
other = baseToString(other);
|
||||
} else {
|
||||
value = baseToNumber(value);
|
||||
other = baseToNumber(other);
|
||||
}
|
||||
result = operator(value, other);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a function like `_.over`.
|
||||
*
|
||||
@@ -4727,6 +4796,23 @@
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a function that performs a relational operation on two values.
|
||||
*
|
||||
* @private
|
||||
* @param {Function} operator The function to perform the operation.
|
||||
* @returns {Function} Returns the new relational operation function.
|
||||
*/
|
||||
function createRelationalOperation(operator) {
|
||||
return function(value, other) {
|
||||
if (!(typeof value == 'string' && typeof other == 'string')) {
|
||||
value = toNumber(value);
|
||||
other = toNumber(other);
|
||||
}
|
||||
return operator(value, other);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a function that wraps `func` to continue currying.
|
||||
*
|
||||
@@ -5544,7 +5630,7 @@
|
||||
*/
|
||||
function isKey(value, object) {
|
||||
var type = typeof value;
|
||||
if (type == 'number' || type == 'symbol') {
|
||||
if (type == 'number' || type == 'boolean' || type == 'symbol' || value == null) {
|
||||
return true;
|
||||
}
|
||||
return !isArray(value) &&
|
||||
@@ -5561,8 +5647,8 @@
|
||||
*/
|
||||
function isKeyable(value) {
|
||||
var type = typeof value;
|
||||
return type == 'number' || type == 'boolean' ||
|
||||
(type == 'string' && value != '__proto__') || value == null;
|
||||
return type == 'number' || type == 'boolean' || type == 'symbol' || value == null ||
|
||||
(type == 'string' && value != '__proto__');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5813,8 +5899,8 @@
|
||||
* @param {*} value The value to inspect.
|
||||
* @returns {string|symbol} Returns the key.
|
||||
*/
|
||||
function toKey(key) {
|
||||
return (typeof key == 'string' || isSymbol(key)) ? key : (key + '');
|
||||
function toKey(value) {
|
||||
return (typeof value == 'string' || isSymbol(value)) ? value : (value + '');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6839,8 +6925,13 @@
|
||||
var pullAt = rest(function(array, indexes) {
|
||||
indexes = baseFlatten(indexes, 1);
|
||||
|
||||
var result = baseAt(array, indexes);
|
||||
basePullAt(array, indexes.sort(compareAscending));
|
||||
var length = array ? array.length : 0,
|
||||
result = baseAt(array, indexes);
|
||||
|
||||
basePullAt(array, arrayMap(indexes, function(index) {
|
||||
return isIndex(index, length) ? +index : index;
|
||||
}).sort(compareAscending));
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
@@ -10253,9 +10344,7 @@
|
||||
* _.gt(1, 3);
|
||||
* // => false
|
||||
*/
|
||||
function gt(value, other) {
|
||||
return value > other;
|
||||
}
|
||||
var gt = createRelationalOperation(baseGt);
|
||||
|
||||
/**
|
||||
* Checks if `value` is greater than or equal to `other`.
|
||||
@@ -10279,9 +10368,9 @@
|
||||
* _.gte(1, 3);
|
||||
* // => false
|
||||
*/
|
||||
function gte(value, other) {
|
||||
var gte = createRelationalOperation(function(value, other) {
|
||||
return value >= other;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Checks if `value` is likely an `arguments` object.
|
||||
@@ -11331,9 +11420,7 @@
|
||||
* _.lt(3, 1);
|
||||
* // => false
|
||||
*/
|
||||
function lt(value, other) {
|
||||
return value < other;
|
||||
}
|
||||
var lt = createRelationalOperation(baseLt);
|
||||
|
||||
/**
|
||||
* Checks if `value` is less than or equal to `other`.
|
||||
@@ -11357,9 +11444,9 @@
|
||||
* _.lte(3, 1);
|
||||
* // => false
|
||||
*/
|
||||
function lte(value, other) {
|
||||
var lte = createRelationalOperation(function(value, other) {
|
||||
return value <= other;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Converts `value` to an array.
|
||||
@@ -11497,8 +11584,9 @@
|
||||
if (typeof value == 'number') {
|
||||
return value;
|
||||
}
|
||||
if (isSymbol(value)) {
|
||||
return NAN;
|
||||
var result = baseToNumber(value);
|
||||
if (result !== result) {
|
||||
return result;
|
||||
}
|
||||
if (isObject(value)) {
|
||||
var other = isFunction(value.valueOf) ? value.valueOf() : value;
|
||||
@@ -11592,17 +11680,10 @@
|
||||
* // => '1,2,3'
|
||||
*/
|
||||
function toString(value) {
|
||||
// Exit early for strings to avoid a performance hit in some environments.
|
||||
if (typeof value == 'string') {
|
||||
return value;
|
||||
}
|
||||
if (value == null) {
|
||||
return '';
|
||||
}
|
||||
if (isSymbol(value)) {
|
||||
return symbolToString ? symbolToString.call(value) : '';
|
||||
}
|
||||
var result = (value + '');
|
||||
var result = baseToString(value);
|
||||
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
|
||||
}
|
||||
|
||||
@@ -15195,7 +15276,7 @@
|
||||
*/
|
||||
function max(array) {
|
||||
return (array && array.length)
|
||||
? baseExtremum(array, identity, gt)
|
||||
? baseExtremum(array, identity, baseGt)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
@@ -15225,7 +15306,7 @@
|
||||
*/
|
||||
function maxBy(array, iteratee) {
|
||||
return (array && array.length)
|
||||
? baseExtremum(array, getIteratee(iteratee), gt)
|
||||
? baseExtremum(array, getIteratee(iteratee), baseGt)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
@@ -15295,7 +15376,7 @@
|
||||
*/
|
||||
function min(array) {
|
||||
return (array && array.length)
|
||||
? baseExtremum(array, identity, lt)
|
||||
? baseExtremum(array, identity, baseLt)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
@@ -15325,7 +15406,7 @@
|
||||
*/
|
||||
function minBy(array, iteratee) {
|
||||
return (array && array.length)
|
||||
? baseExtremum(array, getIteratee(iteratee), lt)
|
||||
? baseExtremum(array, getIteratee(iteratee), baseLt)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user