Live data from Hacker News

Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript

medium.com

21–30 of 163 posts

Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript

#21
post #3

To quote the tl;dr: ['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. That's hilarious. Everybody loves the syntactic sugar that makes things easy, until the unexpected point where it makes things very hard.

What is the syntactic sugar here? I mostly see a map that doesn't behave how anyone would expect.

Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript

#23
post #4

This isn't strange or surprising. parseInt takes two arguments, the second one is the radix and map will call with three arguments, the value, the index and the whole array. You just have to know this and it might be different in other languages. [ ... ].map(x => ...) is the right way to do this.

The surprising bit comes in with the fact that: 1. parseInt is used with only a single argument in most cases. 2. Only the first argument of map is used in most cases.

Using multiple parameters for those are so uncommon that it's easy not to realise that it's supported.

_If you know all of that_ it may not be surprising to you, but in most cases there is no need for the average developer to know it, making it very surprising when it crops up like this.

Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript

#24
post #11
post #2

Stuff like this is what drives me crazy when I work with dynamic languages like JS or PHP. I have seen a lot of code that looked perfectly fine but suffered from unexpected casts or defaults. I much prefer languages like C#, C++ or TypeScript where the compiler warns me of such problems.

Why would it drive you crazy? This is an example of someone not even knowing how the map function works.

Once you work with several languages it’s really hard to keep track of all this stuff. I never know what exactly evaluates to true vs false in PHP or JavaScript for example. Add to that sloppy programmers on your team who don't check their assumptions it’s really easy to have a ton of subtle bugs in your code.

Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript

#25
post #2

Stuff like this is what drives me crazy when I work with dynamic languages like JS or PHP. I have seen a lot of code that looked perfectly fine but suffered from unexpected casts or defaults. I much prefer languages like C#, C++ or TypeScript where the compiler warns me of such problems.

This has nothing to do with casts or defaults. Map passes multiple parameters and parseInt accepts multiple parameters. Being unaware of the functions you're using is the problem, not some sort of weird gotchas of the language. The code in the title makes multiple assumptions, and those assumptions all proved wrong.

I would argue Javascript silently accepting more arguments than the function signature declares is kinda a gotcha. And that's what leads people to not realise map is passing extra arguments, because `list.map(a => f(a))` works.

Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript

#26
post #2

Stuff like this is what drives me crazy when I work with dynamic languages like JS or PHP. I have seen a lot of code that looked perfectly fine but suffered from unexpected casts or defaults. I much prefer languages like C#, C++ or TypeScript where the compiler warns me of such problems.

This has nothing to do with casts or defaults. Map passes multiple parameters and parseInt accepts multiple parameters. Being unaware of the functions you're using is the problem, not some sort of weird gotchas of the language. The code in the title makes multiple assumptions, and those assumptions all proved wrong.

I think the parent is talking about how C for instance does not have optional parameters (for better or worse), if this was the case for JS everyone who has ever used parseInt would be aware it takes a radix, but then again you also wouldn't be able to just plug it into map arbitrarily.

Not saying one is better than the other, optional parameters can make for much less verbose code, I especially like parameter defaults introduced in ES6.

Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript

#28

Disclaimer: I don't know Javascript, but that's why: > ['1','7','11'].map(console.log) 1 0 [ '1', '7', '11' ] 7 1 [ '1', '7', '11' ] 11 2 [ '1', '7', '11' ] [ undefined, undefined, undefined ] > parseInt(1,0) 1 > parseInt(7,1) NaN > parseInt(11,2) 3 The correct way is: > ['1','7','11'].map(x => parseInt(x)) [ 1, 7, 11 ] same as: > ['1','7','11'].map(x => parseInt(x, 10)) [ 1, 7, 11 ]

Those are unfortunately not the same. The second one (with an explicit radix of 10) is correct; the first is not (or is at least a bit riskier). See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... (ctrl+f for "always").

Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript

#29

Earlier quoted context omitted.

This has nothing to do with casts or defaults. Map passes multiple parameters and parseInt accepts multiple parameters. Being unaware of the functions you're using is the problem, not some sort of weird gotchas of the language. The code in the title makes multiple assumptions, and those assumptions all proved wrong.

A typed language would absolutely fail this at compile time.

[deleted]

Re: Why ['1', '7', '11'].map(parseInt) returns [1, NaN, 3] in JavaScript

#30
post #11
post #2

Stuff like this is what drives me crazy when I work with dynamic languages like JS or PHP. I have seen a lot of code that looked perfectly fine but suffered from unexpected casts or defaults. I much prefer languages like C#, C++ or TypeScript where the compiler warns me of such problems.

Why would it drive you crazy? This is an example of someone not even knowing how the map function works.

> not even knowing how JavaScript implements map in a nonstandard way that breaks simple examples

FTFY.

I know exactly how map works: https://en.m.wikipedia.org/wiki/Map_(higher-order_function)

This is map:

> a higher-order function that applies a given function to each element of a functor, e.g. a list, returning a list of results in the same order.

Since that is not what Array.prototype.map does, it is not map, it is some similar thing that is misnamed as map. If I wanted the index and the array as arguments, I would ask for them.

Post reply on HN