Live data from Hacker News

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

medium.com

81–90 of 163 posts

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

#81

Earlier quoted context omitted.

A typed language would absolutely fail this at compile time.

Only because map's third provided argument exists. If map only supplied element and index to the callback, this would pass most type checkers I'm familiar with, and would remain just as confusing.

Precisely - this is an API design failure, pure and simple. Not a problem with typing, optional arguments, etc.

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

#83
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.

What's wrong with just:

[...].map(Number)

?

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

#85

Earlier quoted context omitted.

I've developed applications in JS, but don't have extensive experience with it, and I couldn't spot the problem. Frankly, I think if `['1', '2'].map(parseInt)` is both valid and does not result in a collection containing the integers 1 and 2 in that order, that indicates a catastrophic failure of design at some level. These things happen, but usually you have to dig down to a less bog standard example to find it. The…

The problem is that this article is attributing this problem to JS, whereas the problem is with either computer science or human decimal bias: i.e. the radix is not a concept invented by JS. If you think it should be ok for all devs to believe that parseInt === parseDecimalInt then maybe all languages should be decimal-only. That isn't the case though.

All languages I know of _default_ to a radix of 10 though, allowing other radixes where a prefix is added like 0b111010, 0xa7b45fd9, etc.

Seems intuitive that if parseInt allows omitting the radix parameter, that it should default to whatever radix a standard integer primitive would default to.

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

#86

Earlier quoted context omitted.

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 su…

> in most cases there is no need for the average developer to know it This may come off as arrogant but.. I'll proceed nonetheless. There is a need for the average developer to know the interfaces of the functions they're choosing to use. They're well documented, and the documentation is neither hard to find, nor difficult to read. There may be an argument here for strongly typed languages -vs- weakly typed ones, whe…

I don't understand why this is downvoted to death without any replies. Sounds like a reasonable opinion but I'd also love to hear why people think it's downvote-worthy.

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

#87
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 su…

Why would you use parseInt over Math.round if you only expect a single arg?

Seems like you'd only want to use parseInt if you expect to need radix changes at some point, e.g. converting between hex strings, decimal values, and binary strings

    ['1', '7', '11'].map(Math.round)
    // => [1, 7, 11]

    [["00000001", 2], ["00000111", 2], ["0x0B", 16]].map(x => parseInt(...x))
    // => [1, 7, 11]

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

#88

Earlier quoted context omitted.

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 su…

Why would you use parseInt over Math.round if you only expect a single arg? Seems like you'd only want to use parseInt if you expect to need radix changes at some point, e.g. converting between hex strings, decimal values, and binary strings ['1', '7', '11'].map(Math.round) // => [1, 7, 11] [["00000001", 2], ["00000111", 2], ["0x0B", 16]].map(x => parseInt(...x)) // => [1, 7, 11]

To someone reading the code, parseInt actually describes what your intent is while Math.round just happens to work because it coerces the type.

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

#89

Earlier quoted context omitted.

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 su…

> in most cases there is no need for the average developer to know it This may come off as arrogant but.. I'll proceed nonetheless. There is a need for the average developer to know the interfaces of the functions they're choosing to use. They're well documented, and the documentation is neither hard to find, nor difficult to read. There may be an argument here for strongly typed languages -vs- weakly typed ones, whe…

The part that is relatively unique to JS is where extra arguments passed to a function are silently ignored. In most every other language, the function passed to map takes 1 argument, which is also the common case in JS. But JS always passes 3 arguments to that function. I don't think it's optional parameters that people find confusing, it's the interplay between optional parameters and functions whose interface depends on functions they accept as arguments ignoring extra arguments.

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

#90
tl;dr: parseInt takes an optional second argument, the radix. It defaults to 10 (so the number is parsed in base 10). Since map() passes in each item in the array as the first argument, and the index as the second, you're parsing each string with the radix of whatever the index is.

Not too weird IMO.

Post reply on HN