From 9a461a5e480056040f1cdbca7836a1b8d335161c Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Wed, 4 May 2016 21:09:28 -0700 Subject: [PATCH] Add `_.toFinite`. --- lodash.js | 92 ++++++++++++++++++++++++++++++++++------------------ test/test.js | 37 +++++++++++++-------- 2 files changed, 85 insertions(+), 44 deletions(-) diff --git a/lodash.js b/lodash.js index 397a2928f..69a7403a8 100644 --- a/lodash.js +++ b/lodash.js @@ -1416,10 +1416,10 @@ * `floor`, `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, * `forOwnRight`, `get`, `gt`, `gte`, `has`, `hasIn`, `head`, `identity`, * `includes`, `indexOf`, `inRange`, `invoke`, `isArguments`, `isArray`, - * `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`, `isBuffer`, - * `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, `isError`, - * `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMap`, `isMatch`, - * `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`, + * `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`, + * `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, + * `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMap`, + * `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`, * `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, `isSafeInteger`, * `isSet`, `isString`, `isUndefined`, `isTypedArray`, `isWeakMap`, `isWeakSet`, * `join`, `kebabCase`, `last`, `lastIndexOf`, `lowerCase`, `lowerFirst`, @@ -1428,9 +1428,9 @@ * `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, `round`, * `runInContext`, `sample`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, * `sortedIndexBy`, `sortedLastIndex`, `sortedLastIndexBy`, `startCase`, - * `startsWith`, `subtract`, `sum`, `sumBy`, `template`, `times`, `toInteger`, - * `toJSON`, `toLength`, `toLower`, `toNumber`, `toSafeInteger`, `toString`, - * `toUpper`, `trim`, `trimEnd`, `trimStart`, `truncate`, `unescape`, + * `startsWith`, `subtract`, `sum`, `sumBy`, `template`, `times`, `toFinite`, + * `toInteger`, `toJSON`, `toLength`, `toLower`, `toNumber`, `toSafeInteger`, + * `toString`, `toUpper`, `trim`, `trimEnd`, `trimStart`, `truncate`, `unescape`, * `uniqueId`, `upperCase`, `upperFirst`, `value`, and `words` * * @name _ @@ -10858,14 +10858,14 @@ * _.isFinite(3); * // => true * - * _.isFinite(Number.MAX_VALUE); - * // => true - * - * _.isFinite(3.14); + * _.isFinite(Number.MIN_VALUE); * // => true * * _.isFinite(Infinity); * // => false + * + * _.isFinite('3'); + * // => false */ function isFinite(value) { return typeof value == 'number' && nativeIsFinite(value); @@ -11586,6 +11586,41 @@ return func(value); } + /** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ + function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; + } + /** * Converts `value` to an integer. * @@ -11600,7 +11635,7 @@ * @returns {number} Returns the converted integer. * @example * - * _.toInteger(3); + * _.toInteger(3.2); * // => 3 * * _.toInteger(Number.MIN_VALUE); @@ -11609,20 +11644,14 @@ * _.toInteger(Infinity); * // => 1.7976931348623157e+308 * - * _.toInteger('3'); + * _.toInteger('3.2'); * // => 3 */ function toInteger(value) { - if (!value) { - return value === 0 ? value : 0; - } - value = toNumber(value); - if (value === INFINITY || value === -INFINITY) { - var sign = (value < 0 ? -1 : 1); - return sign * MAX_INTEGER; - } - var remainder = value % 1; - return value === value ? (remainder ? value - remainder : value) : 0; + var result = toFinite(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; } /** @@ -11640,7 +11669,7 @@ * @returns {number} Returns the converted integer. * @example * - * _.toLength(3); + * _.toLength(3.2); * // => 3 * * _.toLength(Number.MIN_VALUE); @@ -11649,7 +11678,7 @@ * _.toLength(Infinity); * // => 4294967295 * - * _.toLength('3'); + * _.toLength('3.2'); * // => 3 */ function toLength(value) { @@ -11667,8 +11696,8 @@ * @returns {number} Returns the number. * @example * - * _.toNumber(3); - * // => 3 + * _.toNumber(3.2); + * // => 3.2 * * _.toNumber(Number.MIN_VALUE); * // => 5e-324 @@ -11676,8 +11705,8 @@ * _.toNumber(Infinity); * // => Infinity * - * _.toNumber('3'); - * // => 3 + * _.toNumber('3.2'); + * // => 3.2 */ function toNumber(value) { if (typeof value == 'number') { @@ -11740,7 +11769,7 @@ * @returns {number} Returns the converted integer. * @example * - * _.toSafeInteger(3); + * _.toSafeInteger(3.2); * // => 3 * * _.toSafeInteger(Number.MIN_VALUE); @@ -11749,7 +11778,7 @@ * _.toSafeInteger(Infinity); * // => 9007199254740991 * - * _.toSafeInteger('3'); + * _.toSafeInteger('3.2'); * // => 3 */ function toSafeInteger(value) { @@ -15915,6 +15944,7 @@ lodash.sumBy = sumBy; lodash.template = template; lodash.times = times; + lodash.toFinite = toFinite; lodash.toInteger = toInteger; lodash.toLength = toLength; lodash.toLower = toLower; diff --git a/test/test.js b/test/test.js index 5d9457ee8..e9349ab87 100644 --- a/test/test.js +++ b/test/test.js @@ -22994,7 +22994,7 @@ QUnit.module('number coercion methods'); - lodashStable.each(['toInteger', 'toNumber', 'toSafeInteger'], function(methodName) { + lodashStable.each(['toFinite', 'toInteger', 'toNumber', 'toSafeInteger'], function(methodName) { var func = _[methodName]; QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) { @@ -23016,8 +23016,9 @@ }); }); - lodashStable.each(['toInteger', 'toLength', 'toNumber', 'toSafeInteger'], function(methodName) { + lodashStable.each(['toFinite', 'toInteger', 'toLength', 'toNumber', 'toSafeInteger'], function(methodName) { var func = _[methodName], + isToFinite = methodName == 'toFinite', isToLength = methodName == 'toLength', isToNumber = methodName == 'toNumber', isToSafeInteger = methodName == 'toSafeInteger'; @@ -23055,7 +23056,7 @@ var expected = lodashStable.map(values, function(value) { if (!isToNumber) { - if (value == 1.2) { + if (!isToFinite && value == 1.2) { value = 1; } else if (value == Infinity) { @@ -23094,13 +23095,13 @@ var expected = lodashStable.map(values, function(value) { var n = +value; if (!isToNumber) { - if (n == 1.234567890) { + if (!isToFinite && n == 1.234567890) { n = 1; } else if (n == Infinity) { n = MAX_INTEGER; } - else if (n == Number.MIN_VALUE || n !== n) { + else if ((!isToFinite && n == Number.MIN_VALUE) || n !== n) { n = 0; } if (isToLength || isToSafeInteger) { @@ -23216,20 +23217,29 @@ ]; var expected = [ - NaN, 0, 1, NaN, - NaN, 2.2, 1.1, 1.1, + NaN, 0, 1, NaN, + NaN, 2.2, 1.1, 1.1, NaN, NaN, 5349, 5349, 42, 42 ]; - if (!isToNumber) { + if (isToFinite) { expected = [ - 0, 0, 1, 0, - 0, 2, 1, 1, - 0, 0, + 0, 0, 1, 0, + 0, 2.2, 1.1, 1.1, + 0, 0, 5349, 5349, - 42, 42 + 42, 42 + ]; + } + else if (!isToNumber) { + expected = [ + 0, 0, 1, 0, + 0, 2, 1, 1, + 0, 0, + 5349, 5349, + 42, 42 ]; } var actual = lodashStable.map(values, func); @@ -25946,6 +25956,7 @@ 'startsWith', 'subtract', 'sum', + 'toFinite', 'toInteger', 'toLower', 'toNumber', @@ -26203,7 +26214,7 @@ var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey); QUnit.test('should accept falsey arguments', function(assert) { - assert.expect(308); + assert.expect(309); var emptyArrays = lodashStable.map(falsey, alwaysEmptyArray);