The reason for this is that parseInt actually takes 2 arguments (string and radix). Map accepts methods that take up to 3 arguments (value, index, and array). So, when passed to map directly, string is getting value (what we expect!), but index is being passed as the radix. Meaning, you try to parse the 0th element in a natural way (base 10), then you try to parse the 1st element as base one (which it's not a valid base 1 number, so NaN), parse the 2nd element as base two (again, 3 is not valid base 2, so NaN), and so on...
I've been bitten by this bug quite a few times. When using map, bypassing the anonymous function and passing a named function should generally only be used if the function takes a single argument.
Software dev at Netflix | DC techie | Conference speaker | egghead Instructor | TC39 Educators Committee | Girls Who Code Facilitator | Board game geek | @laurieontech on twitter
The default behaviour of Array.map is unintuitive given that it returns the index and the original array as the second and third arguments to the callback function respectively.
I would approach the parseInt problem by writing a map function that takes two args, supplied one at a time (to facilitate partial application).
the first arg, a function f that will be supplied only one value at a time, that is, the current iterated value
the second arg, a 1-dimensional array of values to apply the function f on
It may appear complicated seeing it for the first time, but come back to the example and mull it over and it will start to click.
The most common pitfall though with this approach is when, for example, converting an array of strings into integers.
The reason for this is that parseInt actually takes 2 arguments (string and radix). Map accepts methods that take up to 3 arguments (value, index, and array). So, when passed to map directly, string is getting value (what we expect!), but index is being passed as the radix. Meaning, you try to parse the 0th element in a natural way (base 10), then you try to parse the 1st element as base one (which it's not a valid base 1 number, so NaN), parse the 2nd element as base two (again, 3 is not valid base 2, so NaN), and so on...
I've been bitten by this bug quite a few times. When using map, bypassing the anonymous function and passing a named function should generally only be used if the function takes a single argument.
Though it might be a distraction from the example... You could put
Number
there in place ofparseInt
.That's a good one! Thanks for pointing it out.
The default behaviour of
Array.map
is unintuitive given that it returns the index and the original array as the second and third arguments to the callback function respectively.I would approach the
parseInt
problem by writing a map function that takes two args, supplied one at a time (to facilitate partial application).f
that will be supplied only one value at a time, that is, the current iterated valuef
onIt may appear complicated seeing it for the first time, but come back to the example and mull it over and it will start to click.
But why include
index
andoriginalArray
parameters when you don't use them?For that matter, why not make this point-free?
(... and around in circles we go!)
That's true, they are superfluous - I left those other args there to make it clearer how the args are moving around.