98

Possible Duplicate:
javascript - Array.map and parseInt

I saw this example of strange JavaScript behavior on twitter

['10','10','10','10','10'].map(parseInt)

evaluates to

[10, NaN, 2, 3, 4]

could somebody explain this behavior? I verified it in chrome and firebug

['10','10','10','10','10'].map(function(x){return parseInt(x);})

correctly returns an array of 10s as integers. Is this an improper use of map(), a bug with parseInt, or something else?

Community
  • 1
  • 1
Ben McCormick
  • 25,260
  • 12
  • 52
  • 71
  • yep, this showed up in related when I posted it, but not in the search results as I was writing it. I have no problem with it being closed as a duplicate. – Ben McCormick Jan 25 '13 at 18:59
  • There was also another similar question recently (this week, I think). I was trying to find that, could only find the one I linked to. – bfavaretto Jan 25 '13 at 19:01
  • This is actually the one I saw: http://stackoverflow.com/questions/8594699/map-parseint-strange-results?lq=1 I think the answers here have been better than that one, but the older one you mentioned is also very clear. – Ben McCormick Jan 25 '13 at 19:04
  • A workaround could be to create your own wrapper around parseInt, like this: `const toInt = (value) => parseInt(value);`. This will works as you expected. Then use it like this: `['10','10','10','10','10'].map(toInt)` – LTroya Nov 06 '17 at 18:32
  • You can also use lodash's `_.toInteger()` function with lodash `_.map()` to accomplish your goal: `_.map(['10','10'], _.toInteger);` – steampowered Jan 15 '20 at 16:22

3 Answers3

113

parseInt receives two arguments: string and radix:

var intValue = parseInt(string[, radix]);

while map handler's second argument is index:

... callback is invoked with three arguments: the value of the element, the index of the element, and the Array object being traversed.

Geoff Dalgas
  • 6,116
  • 6
  • 42
  • 58
VisioN
  • 143,310
  • 32
  • 282
  • 281
  • 2
    ah that makes sense, so the 2nd number is trying to evaluate in base 1 and fails and the rest will just return the index? That makes sense. Thanks. – Ben McCormick Jan 25 '13 at 18:50
  • 3
    The rest aren't strictly "returning the index", but it works out the same because any number `x` in base `x` is represented as the string `'10'`. Note that if you have more than 36 elements in your array of `'10'`s, you'll start getting more `NaN`s at the end. – Gareth Jan 27 '13 at 14:32
  • is there a workaround to make this work ? thx – Vincent Wasteels Nov 12 '14 at 16:53
  • 2
    @VincentWasteels Yes, sort of. You may use `[...].map(parseFloat)` or `[...].map(Number)`. Both will cast strings to numbers in the given array. However `parseFloat` and `Number` work slightly different than `parseInt`: both will cast floats as well as integers, while `Number` will turn strings that start with digits and have other characters included into `NaN` (e.g. `10abc`). `Number` can also cast all space and non printable characters to `0`. As a string to number converter both work pretty well, if only you *really* need to use `parseInt`: then use anonymous function as `map` argument. – VisioN Nov 13 '14 at 09:51
  • Correct answer but doesn't offer a solution or alternative. – David Prieto Sep 05 '17 at 12:34
  • @DavidPrieto please check my comment right before your one. – VisioN Sep 06 '17 at 19:19
36

parseInt uses the first two arguments being passed in by map, and uses the second argument to specify the radix.

Here's what's happening in your code:

parseInt('10', 0) // 10
parseInt('10', 1) // NaN
parseInt('10', 2) // 2
parseInt('10', 3) // 3
parseInt('10', 4) // 4

Here's a link to MDN on parseInt: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/parseInt.

Joseph Silber
  • 214,931
  • 59
  • 362
  • 292
  • 4
    `parseInt('10', 0) // 10` doesn't really make any more sense than base-1. That too should've been NaN. But I guess in a language where null, 0, false, undefined and '' are pretty much the same thing, I can sorta get why. `if (radix) {...} else {...assume base 10...}`. So basically undefined and 0 are both falsy, so they take the same codepath – kornfridge Aug 15 '16 at 17:07
  • @kornfridge That's explained in the link under *"If radix is undefined or 0 (or absent)"* – wjandrea Mar 20 '19 at 22:17
5

From MDN:

callback is invoked with three arguments: the value of the element, the index of the element, and the Array object being traversed.

parseInt() takes two arguments. The value and the radix. That means that the parseInt() function is being called with unintended parameters.

Justin Niessner
  • 242,243
  • 40
  • 408
  • 536