Why you should never map(parseInt)

lucis profile image Lucis ・2 min read

I've just caught this simple bug in a code I'm building right on the browser's editor (simple things, no typechecking) and now I remember it's not the first time I've learned this the hard way.

const someStringMaybe = ['08', '10']
const myInts = someStringMaybe.map(parseInt)

That looks neat and simple, but there's an underlying problem that may take you a couple of minutes to get it, specially if it has been a long time since you've dealt with parseInt and numbers stuff with Javascript.

Of course, you probably will chain that array with other operations and, in the end, realize it's broken. Than you realize the reason:

-> myInts
[8, Nan]

If you're familiar with parseInt you will know that parseInt('10') === 10, but, what happened?

By now, an experienced JS programmer should've realized what went wrong, but this could be a real pain for beginners. Yes, parseInt works fine converting string-numbers to numbers but it actually supports base conversion, and it receives a second parameter, as you can see in the docs.

The problems happens because Array.map will always pass 3 arguments: the current value, the index, and the original array. When a function only accepts one argument, the other two are "discarded".

-> someStringMaybe.map(console.log)
   '08' 0 ["08", "10"]
   '10' 1 ["08", "10"]

When you map(parseInt) directly, the index will be interpreted as the base and wild math-things will happen.

The solution:

const myInts = someStringMaybe.map(str => parseInt(str, 10))

(it works without the 10, but it's recommended to always make the base clear for future readers, and also preventing the original problem.)


Editor guide