Was playing around with some code to create an array of 0
's and found that for only one value NaN
was returned instead of 0
. I get this in Chrome, Node, and Firefox.
What's causing the second value to be NaN
?
var arr = new Array(32).join(0).split('').map(parseInt)
// prints [0, NaN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
console.dir(arr)
['1', '7', '11']. map(parseInt) doesn't work as intended because map passes three arguments into parseInt() on each iteration. The second argument index is passed into parseInt as a radix parameter. So, each string in the array is parsed using a different radix.
Nan means “Not a number”, this is because inside your cube function, you're not calling the square function, but getting it's contents. Change return x * square; with return x * square(x); and it should work.
That's because the function passed to map
will be called with three arguments:
In this case, that function is parseInt
, which only uses two arguments:
Therefore, for the 2nd item in the array (i.e. index 1
), the call will be
parseInt("0", 1, ignoredArray)
When the radix is 1
, NaN
is returned:
- Let R = ToInt32(radix).
- If R ≠ 0, then
- If R < 2 or R > 36, then return NaN.
Also note that if you used a bigger number like new Array(99)
, you would have seen NaN
s starting at index 37.
The .map()
function passes three arguments to the callback of which two are used by parseInt()
: the value, and the index (the third is the array itself). When the index is 1
, any string of digits will be an invalid value. The parseInt()
function ignores the second argument when it's 0
.
To elaborate: for the first element, parseInt()
is called like this:
parseInt("0", 0)
because the array value is zero and the index is zero. On the second call, it's this:
parseInt("0", 1)
and that returns NaN
.
Note that if you're not too picky about the results being all integers, you can do what you're trying to do with the Number constructor:
var arr = new Array(32).join(0).split('').map(Number);
In ES2015 (the newest ratified standard for JavaScript, which if we are all very good will be fully implemented in all browsers as our Christmas present) you can use the .fill()
function:
var arr = new Array(31).fill(0);
The mapping passes three arguments to its function:
The parseInt
function will look at the first two of those, treating the first correctly as the string but treating the second as the base to use. When the base is neither zero nor in the inclusive range 2..36
, it returns NaN
(1). If you had an array with forty elements, you'd also see a bunch of NaN
values at the end:
0, NaN, 0, 0, 0, ... 0, 0, 0, NaN, NaN
You'd also get some pretty strange results if the number strings were anything other than zero, since the array index would dictate what base was used to interpret it.
To actually fix this, you can just provide a function that will translate what map
gives you to what parseInt
expects (a map map, I guess you could call it):
function myParseInt(s,r,a) { return parseInt(s,10); }
var arr = new Array(32).join(0).split('').map(myParseInt)
alert(arr)
You might also want to have a look at the way you're creating this array, it will actually end up as an array of size 31 rather than 32. If you just want an array of '0'
characters, you can just use:
var arr = new Array(32).fill('0')
assuming you have a browser that supports ECMAScript 2015, which is Safari, Firefox and Chrome-desktop as of the time of this answer.
(1) A base of zero is the default case for handling things like hex prefixes.
A base of one makes no sense in a purely positional system (where each digit is multiplied by a power of the base and accumulated) since the only allowed digit there would be 0
, so each place value would be that zero multiplied by 1n
. In other words, the only number possible in a base-one system would be zero.
Bases from 2
to 36
are therefore more sensible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With