mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-06 09:47:48 +00:00
Add _.toNumber.
This commit is contained in:
committed by
John-David Dalton
parent
4bc35e9ed4
commit
37955345ef
41
lodash.js
41
lodash.js
@@ -54,7 +54,8 @@
|
|||||||
/** Used as references for various `Number` constants. */
|
/** Used as references for various `Number` constants. */
|
||||||
var INFINITY = 1 / 0,
|
var INFINITY = 1 / 0,
|
||||||
MAX_SAFE_INTEGER = 9007199254740991,
|
MAX_SAFE_INTEGER = 9007199254740991,
|
||||||
MAX_INTEGER = 1.7976931348623157e+308;
|
MAX_INTEGER = 1.7976931348623157e+308,
|
||||||
|
NAN = 0 / 0;
|
||||||
|
|
||||||
/** Used as references for the maximum length and index of an array. */
|
/** Used as references for the maximum length and index of an array. */
|
||||||
var MAX_ARRAY_LENGTH = 4294967295,
|
var MAX_ARRAY_LENGTH = 4294967295,
|
||||||
@@ -126,11 +127,20 @@
|
|||||||
var reFlags = /\w*$/;
|
var reFlags = /\w*$/;
|
||||||
|
|
||||||
/** Used to detect hexadecimal string values. */
|
/** Used to detect hexadecimal string values. */
|
||||||
var reHasHexPrefix = /^0[xX]/;
|
var reHasHexPrefix = /^0x/i;
|
||||||
|
|
||||||
|
/** Used to detect bad signed hex string values. */
|
||||||
|
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
|
||||||
|
|
||||||
|
/** Used to detect binary string values. */
|
||||||
|
var reIsBinary = /^0b[0-1]+$/i;
|
||||||
|
|
||||||
/** Used to detect host constructors (Safari > 5). */
|
/** Used to detect host constructors (Safari > 5). */
|
||||||
var reIsHostCtor = /^\[object .+?Constructor\]$/;
|
var reIsHostCtor = /^\[object .+?Constructor\]$/;
|
||||||
|
|
||||||
|
/** Used to detect octal string values. */
|
||||||
|
var reIsOctal = /^0o[0-7]+$/i;
|
||||||
|
|
||||||
/** Used to detect unsigned integer values. */
|
/** Used to detect unsigned integer values. */
|
||||||
var reIsUint = /^(?:0|[1-9]\d*)$/;
|
var reIsUint = /^(?:0|[1-9]\d*)$/;
|
||||||
|
|
||||||
@@ -9853,7 +9863,7 @@
|
|||||||
* Converts `value` to an integer suitable for use as the length of an
|
* Converts `value` to an integer suitable for use as the length of an
|
||||||
* array-like object.
|
* array-like object.
|
||||||
*
|
*
|
||||||
* **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
|
* **Note:** This method is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
|
||||||
*
|
*
|
||||||
* @static
|
* @static
|
||||||
* @memberOf _
|
* @memberOf _
|
||||||
@@ -9865,6 +9875,30 @@
|
|||||||
return clamp(toInteger(value), 0, MAX_ARRAY_LENGTH);
|
return clamp(toInteger(value), 0, MAX_ARRAY_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts `value` to a number.
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @memberOf _
|
||||||
|
* @category Lang
|
||||||
|
* @param {*} value The value to process.
|
||||||
|
* @returns {number} Returns the number.
|
||||||
|
*/
|
||||||
|
function toNumber(value) {
|
||||||
|
if (isObject(value)) {
|
||||||
|
var other = isFunction(value.valueOf) ? value.valueOf() : value;
|
||||||
|
value = isObject(other) ? (other + '') : other;
|
||||||
|
}
|
||||||
|
if (typeof value == 'number' || !isString(value)) {
|
||||||
|
return +value;
|
||||||
|
}
|
||||||
|
value = trim(value);
|
||||||
|
var isBinary = reIsBinary.test(value);
|
||||||
|
return (isBinary || reIsOctal.test(value))
|
||||||
|
? nativeParseInt(value.slice(2), isBinary ? 2 : 8)
|
||||||
|
: (reIsBadHex.test(value) ? NAN : +value);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts `value` to a plain object flattening inherited enumerable
|
* Converts `value` to a plain object flattening inherited enumerable
|
||||||
* properties of `value` to own properties of the plain object.
|
* properties of `value` to own properties of the plain object.
|
||||||
@@ -13522,6 +13556,7 @@
|
|||||||
lodash.toInteger = toInteger;
|
lodash.toInteger = toInteger;
|
||||||
lodash.toLength = toLength;
|
lodash.toLength = toLength;
|
||||||
lodash.toLower = toLower;
|
lodash.toLower = toLower;
|
||||||
|
lodash.toNumber = toNumber;
|
||||||
lodash.toSafeInteger = toSafeInteger;
|
lodash.toSafeInteger = toSafeInteger;
|
||||||
lodash.toString = toString;
|
lodash.toString = toString;
|
||||||
lodash.toUpper = toUpper;
|
lodash.toUpper = toUpper;
|
||||||
|
|||||||
329
test/test.js
329
test/test.js
@@ -19373,6 +19373,332 @@
|
|||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
QUnit.module('lodash.toNumber');
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
QUnit.test('null, empty strings and undefined should convert to `0` and `NaN`', function(assert) {
|
||||||
|
assert.expect(2);
|
||||||
|
|
||||||
|
assert.deepEqual(_.toNumber(), NaN);
|
||||||
|
var values = [undefined, null, '', whitespace],
|
||||||
|
expected = [NaN, Infinity, Infinity, Infinity],
|
||||||
|
actual = lodashStable.map(values, function(value) {
|
||||||
|
return 1 / _.toNumber(value);
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.deepEqual(actual, expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('zeros should preserve their sign', function(assert) {
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
var temp = [0, '0', ' 0 ', '+0', ' +0 '],
|
||||||
|
values = temp,
|
||||||
|
length = temp.length * 2,
|
||||||
|
expected = _.fill(Array(length), Infinity),
|
||||||
|
actual = lodashStable.reduce(temp, function(acc, value) {
|
||||||
|
acc.push(1 / _.toNumber(value), 1 / _.toNumber(Object(value)));
|
||||||
|
return acc;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
temp = [-0, '-0', ' -0 '];
|
||||||
|
values = values.concat(temp);
|
||||||
|
expected.length += temp.length * 2;
|
||||||
|
_.fill(expected, -Infinity, length);
|
||||||
|
lodashStable.reduce(temp, function(acc, value) {
|
||||||
|
acc.push(1 / _.toNumber(value), 1 / _.toNumber(Object(value)));
|
||||||
|
return acc;
|
||||||
|
}, actual);
|
||||||
|
|
||||||
|
assert.deepEqual(actual, expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
var toNumberNumbers = [10, 1.23456789, MAX_SAFE_INTEGER, MAX_INTEGER, Infinity, NaN];
|
||||||
|
lodashStable.each(toNumberNumbers, function (number) {
|
||||||
|
QUnit.test('number literal and objects should return number literals', function(assert) {
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
var expected = [number, -number, number, -number],
|
||||||
|
actual = [_.toNumber(number), _.toNumber(-number), _.toNumber(Object(number)), _.toNumber(Object(-number))];
|
||||||
|
|
||||||
|
assert.deepEqual(actual, expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function negStr(string) {
|
||||||
|
return '-' + string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function posStr(string) {
|
||||||
|
return '+' + string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function wrapWS(string) {
|
||||||
|
return whitespace + string + whitespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
var toNumberBasicStrings = ['10', '1.234567890', '9007199254740991', '1e+308', '1e308', '1E+308', '1E308', '5e-324', '5E-324', 'Infinity', 'NaN'];
|
||||||
|
lodashStable.each(toNumberNumbers, function (string) {
|
||||||
|
QUnit.test('should convert basic string literals and objects accurately', function(assert) {
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
var actual = [],
|
||||||
|
expected = [];
|
||||||
|
|
||||||
|
actual.push(_.toNumber(string));
|
||||||
|
expected.push(+string);
|
||||||
|
actual.push(_.toNumber(posStr(string)));
|
||||||
|
expected.push(+posStr(string));
|
||||||
|
actual.push(_.toNumber(negStr(string)));
|
||||||
|
expected.push(+negStr(string));
|
||||||
|
actual.push(_.toNumber(wrapWS(string)));
|
||||||
|
expected.push(+string);
|
||||||
|
actual.push(_.toNumber(wrapWS(posStr(string))));
|
||||||
|
expected.push(+posStr(string));
|
||||||
|
actual.push(_.toNumber(wrapWS(negStr(string))));
|
||||||
|
expected.push(+negStr(string));
|
||||||
|
|
||||||
|
actual.push(_.toNumber(Object(string))),
|
||||||
|
expected.push(+string);
|
||||||
|
actual.push(_.toNumber(Object(posStr(string))));
|
||||||
|
expected.push(+posStr(string));
|
||||||
|
actual.push(_.toNumber(Object(negStr(string))));
|
||||||
|
expected.push(+negStr(string));
|
||||||
|
actual.push(_.toNumber(Object(wrapWS(string))));
|
||||||
|
expected.push(+string);
|
||||||
|
actual.push(_.toNumber(Object(wrapWS(posStr(string)))));
|
||||||
|
expected.push(+posStr(string));
|
||||||
|
actual.push(_.toNumber(Object(wrapWS(negStr(string)))));
|
||||||
|
expected.push(+negStr(string));
|
||||||
|
|
||||||
|
assert.deepEqual(actual, expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
var toNumberAdvancedStrings = [{
|
||||||
|
string: '0b101010',
|
||||||
|
value: 42
|
||||||
|
}, {
|
||||||
|
string: '0o12345',
|
||||||
|
value: 5349
|
||||||
|
}, {
|
||||||
|
string: '0x1a2b3c',
|
||||||
|
value: 1715004
|
||||||
|
}];
|
||||||
|
lodashStable.each(toNumberAdvancedStrings, function (item) {
|
||||||
|
QUnit.test('should convert basic string literals and objects accurately', function(assert) {
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
var actual = [],
|
||||||
|
expected = [];
|
||||||
|
|
||||||
|
actual.push(_.toNumber(item.string));
|
||||||
|
expected.push(item.value);
|
||||||
|
actual.push(_.toNumber(posStr(item.string)));
|
||||||
|
expected.push(NaN);
|
||||||
|
actual.push(_.toNumber(negStr(item.string)));
|
||||||
|
expected.push(NaN);
|
||||||
|
actual.push(_.toNumber(wrapWS(item.string)));
|
||||||
|
expected.push(item.value);
|
||||||
|
actual.push(_.toNumber(wrapWS(posStr(item.string))));
|
||||||
|
expected.push(NaN);
|
||||||
|
actual.push(_.toNumber(wrapWS(negStr(item.string))));
|
||||||
|
expected.push(NaN);
|
||||||
|
|
||||||
|
actual.push(_.toNumber(item.string.toUpperCase()));
|
||||||
|
expected.push(item.value);
|
||||||
|
actual.push(_.toNumber(posStr(item.string.toUpperCase())));
|
||||||
|
expected.push(NaN);
|
||||||
|
actual.push(_.toNumber(negStr(item.string.toUpperCase())));
|
||||||
|
expected.push(NaN);
|
||||||
|
actual.push(_.toNumber(wrapWS(item.string.toUpperCase())));
|
||||||
|
expected.push(item.value);
|
||||||
|
actual.push(_.toNumber(wrapWS(posStr(item.string.toUpperCase()))));
|
||||||
|
expected.push(NaN);
|
||||||
|
actual.push(_.toNumber(wrapWS(negStr(item.string.toUpperCase()))));
|
||||||
|
expected.push(NaN);
|
||||||
|
|
||||||
|
actual.push(_.toNumber(Object(item.string)));
|
||||||
|
expected.push(item.value);
|
||||||
|
actual.push(_.toNumber(Object(posStr(item.string))));
|
||||||
|
expected.push(NaN);
|
||||||
|
actual.push(_.toNumber(Object(negStr(item.string))));
|
||||||
|
expected.push(NaN);
|
||||||
|
actual.push(_.toNumber(Object(wrapWS(item.string))));
|
||||||
|
expected.push(item.value);
|
||||||
|
actual.push(_.toNumber(Object(wrapWS(posStr(item.string)))));
|
||||||
|
expected.push(NaN);
|
||||||
|
actual.push(_.toNumber(Object(wrapWS(negStr(item.string)))));
|
||||||
|
expected.push(NaN);
|
||||||
|
|
||||||
|
actual.push(_.toNumber(Object(item.string.toUpperCase())));
|
||||||
|
expected.push(item.value);
|
||||||
|
actual.push(_.toNumber(Object(posStr(item.string.toUpperCase()))));
|
||||||
|
expected.push(NaN);
|
||||||
|
actual.push(_.toNumber(Object(negStr(item.string.toUpperCase()))));
|
||||||
|
expected.push(NaN);
|
||||||
|
actual.push(_.toNumber(Object(wrapWS(item.string.toUpperCase()))));
|
||||||
|
expected.push(item.value);
|
||||||
|
actual.push(_.toNumber(Object(wrapWS(posStr(item.string.toUpperCase())))));
|
||||||
|
expected.push(NaN);
|
||||||
|
actual.push(_.toNumber(Object(wrapWS(negStr(item.string.toUpperCase())))));
|
||||||
|
expected.push(NaN);
|
||||||
|
|
||||||
|
assert.deepEqual(actual, expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
var toNumberInvalidAdvanceStrings = ['0b', '0o', '0x', '0b1010102', '0o123458', '0x1a2b3x'];
|
||||||
|
lodashStable.each(toNumberInvalidAdvanceStrings, function (string) {
|
||||||
|
QUnit.test('invalid binary, octal and hex string literals and objects should be `NaN`', function(assert) {
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
var actual = [];
|
||||||
|
|
||||||
|
actual.push(_.toNumber(string));
|
||||||
|
actual.push(_.toNumber(posStr(string)));
|
||||||
|
actual.push(_.toNumber(negStr(string)));
|
||||||
|
actual.push(_.toNumber(wrapWS(string)));
|
||||||
|
actual.push(_.toNumber(wrapWS(posStr(string))));
|
||||||
|
actual.push(_.toNumber(wrapWS(negStr(string))));
|
||||||
|
|
||||||
|
actual.push(_.toNumber(Object(string)));
|
||||||
|
actual.push(_.toNumber(Object(posStr(string))));
|
||||||
|
actual.push(_.toNumber(Object(negStr(string))));
|
||||||
|
actual.push(_.toNumber(Object(wrapWS(string))));
|
||||||
|
actual.push(_.toNumber(Object(wrapWS(posStr(string)))));
|
||||||
|
actual.push(_.toNumber(Object(wrapWS(negStr(string)))));
|
||||||
|
|
||||||
|
var expected = _.fill(Array(actual.length), NaN);
|
||||||
|
assert.deepEqual(actual, expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('should convert boolean literals and objects', function(assert) {
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
var actual = [],
|
||||||
|
expected = [];
|
||||||
|
|
||||||
|
actual.push(1 / _.toNumber(false));
|
||||||
|
expected.push(Infinity);
|
||||||
|
actual.push(_.toNumber(true));
|
||||||
|
expected.push(1);
|
||||||
|
actual.push(1 / _.toNumber(new Boolean(false)));
|
||||||
|
expected.push(Infinity);
|
||||||
|
actual.push(_.toNumber(new Boolean(true)));
|
||||||
|
expected.push(1);
|
||||||
|
actual.push(_.toNumber('false'));
|
||||||
|
expected.push(NaN);
|
||||||
|
actual.push(_.toNumber('true'));
|
||||||
|
expected.push(NaN);
|
||||||
|
|
||||||
|
assert.deepEqual(actual, expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('should convert dates', function(assert) {
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
var now = new Date(),
|
||||||
|
actual = [_.toNumber(now), _.toNumber(new Date(MAX_INTEGER))],
|
||||||
|
expected = [now.getTime(), NaN];
|
||||||
|
|
||||||
|
assert.deepEqual(actual, expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('should convert RegExp literals and objects', function(assert) {
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
var actual = [_.toNumber(/abc/i), _.toNumber(new RegExp('abc', 'i'))],
|
||||||
|
expected = [NaN, NaN];
|
||||||
|
|
||||||
|
assert.deepEqual(actual, expected);
|
||||||
|
})
|
||||||
|
|
||||||
|
QUnit.test('other objects', function(assert) {
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
var actual = [],
|
||||||
|
expected = [];
|
||||||
|
|
||||||
|
actual.push(_.toNumber({}));
|
||||||
|
expected.push(NaN);
|
||||||
|
actual.push(_.toNumber({
|
||||||
|
valueOf: '1.1'
|
||||||
|
}));
|
||||||
|
expected.push(NaN);
|
||||||
|
actual.push(_.toNumber({
|
||||||
|
valueOf: '1.1',
|
||||||
|
toString: function () {
|
||||||
|
return '2.2';
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
expected.push(2.2);
|
||||||
|
actual.push(_.toNumber({
|
||||||
|
valueOf: function () {
|
||||||
|
return '1.1';
|
||||||
|
},
|
||||||
|
toString: '2.2'
|
||||||
|
}));
|
||||||
|
expected.push(1.1);
|
||||||
|
actual.push(_.toNumber({
|
||||||
|
valueOf: function () {
|
||||||
|
return '1.1';
|
||||||
|
},
|
||||||
|
toString: function () {
|
||||||
|
return '2.2';
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
expected.push(1.1);
|
||||||
|
actual.push(_.toNumber({
|
||||||
|
valueOf: function () {
|
||||||
|
return '-0x1a2b3c';
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
expected.push(NaN);
|
||||||
|
actual.push(_.toNumber({
|
||||||
|
toString: function () {
|
||||||
|
return '-0x1a2b3c';
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
expected.push(NaN);
|
||||||
|
actual.push(_.toNumber({
|
||||||
|
valueOf: function () {
|
||||||
|
return '0o12345';
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
expected.push(5349);
|
||||||
|
actual.push(_.toNumber({
|
||||||
|
toString: function () {
|
||||||
|
return '0o12345';
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
expected.push(5349);
|
||||||
|
actual.push(_.toNumber({
|
||||||
|
valueOf: function () {
|
||||||
|
return '0b101010';
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
expected.push(42);
|
||||||
|
actual.push(_.toNumber({
|
||||||
|
toString: function () {
|
||||||
|
return '0b101010';
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
expected.push(42);
|
||||||
|
actual.push(1 / _.toNumber([]));
|
||||||
|
expected.push(Infinity);
|
||||||
|
actual.push(_.toNumber([1]));
|
||||||
|
expected.push(1);
|
||||||
|
actual.push(_.toNumber([1, 2]));
|
||||||
|
expected.push(NaN);
|
||||||
|
|
||||||
|
assert.deepEqual(actual, expected);
|
||||||
|
});
|
||||||
|
}());
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
QUnit.module('lodash.toPath');
|
QUnit.module('lodash.toPath');
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
@@ -21801,6 +22127,7 @@
|
|||||||
'sum',
|
'sum',
|
||||||
'toInteger',
|
'toInteger',
|
||||||
'toLower',
|
'toLower',
|
||||||
|
'toNumber',
|
||||||
'toSafeInteger',
|
'toSafeInteger',
|
||||||
'toString',
|
'toString',
|
||||||
'toUpper',
|
'toUpper',
|
||||||
@@ -22058,7 +22385,7 @@
|
|||||||
var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey);
|
var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey);
|
||||||
|
|
||||||
QUnit.test('should accept falsey arguments', function(assert) {
|
QUnit.test('should accept falsey arguments', function(assert) {
|
||||||
assert.expect(274);
|
assert.expect(275);
|
||||||
|
|
||||||
var emptyArrays = lodashStable.map(falsey, lodashStable.constant([]));
|
var emptyArrays = lodashStable.map(falsey, lodashStable.constant([]));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user