4

I was resolving some problems on codewars and tried to convert a string to a list of numbers like this:

"102904".split("").map(parseInt);

The expected result would be something like this:

[1, 0, 2, 9, 0, 4]

But it returns instead:

[1, NaN, NaN, NaN, 0, 4]

At believe that map should apply to each element in the list which are strings of 1 digits. One could believe that it isn't parsing correctly because the base isn't used but:

"102904".split("").map(function(x){ return parseInt(x);});
[ 1, 0, 2, 9, 0, 4]

Using parseInt(x, 10), doesn't change the result. But sending directly parseInt to map creates NaN...

I tried on Chrome and Firefox and I receive the same results.

Loïc Faure-Lacroix
  • 13,220
  • 6
  • 67
  • 99

3 Answers3

7

parseInt involves second argument - radix.

Your problem is that - map sends to arguments: item itself and index.

Problem digits are: 0, 2, 9

Why ?

  • 0 - has radix passed as 1. 1 isn't a legal radix so NaN
  • 2 - has radix passed as 2. In 2 base 2 is not available digit(0 and 1 are)
  • 9 - has radix passed as 3. Still 9 is not a valid digit(0, 1 and 2 are)
lukas.pukenis
  • 13,057
  • 12
  • 47
  • 81
1
"102904".split("").map(function(x, y){ console.log(x, y) });

returns

1 0
0 1
2 2
9 3
0 4
4 5

This means that, in your first example, parseInt gets called like this:

parseInt("1", 0);
parseInt("0", 1);
parseInt("2", 2);
parseInt("9", 3);
// ecc...

You're passing the index of the iteration as a second parameter to parseInt() (which represents the radix of the number to be parsed).


The best solution is to use the second approach, with the code you already posted.

Saturnix
  • 10,130
  • 17
  • 64
  • 120
1

The function provided as the callback to Array.prototype.map receives three arguments:

  • the element from the array
  • the index in the array
  • the array itself

If you provide two arguments to parseInt, the second is treated as the radix – the numerical base to parse the number in. So you string is parsed like this

string | base | result
----------------------
1      | 0    | 1
0      | 1    | NaN
2      | 2    | NaN
9      | 3    | NaN
0      | 4    | 0
4      | 5    | 4

The surprising behaviour here is that using base 0 (which is impossible), the result is 1 rather than NaN. This is because parseInt treats a radix of 0 as if it were not provided:

If radix is undefined or 0 (or absent), JavaScript assumes the following: (MDN docs)

lonesomeday
  • 233,373
  • 50
  • 316
  • 318