HowTo

1 | Problem?

This is weird? Isn’t it. JavaScript is full of such type of cases. I know you must be expecting that it should return [1, 5, 11]. Then why it is behaving in such an unexpected manner?

HowGif

Don’t worry buddy. In this post, we are going to break it down to basics and will understand it’s behavior.

. . .

2 | Solution?

Let’s see what is parseInt and how it works

The parseInt() function parses a string argument and returns an integer of the specified radix (the base in methematical numeral systems).

Syntax: parseInt(string, radix)

Radix: An integer between 2 and 36 that represents the radix (the base in mathematical numeral systems) of the string. Be careful — this does not default to 10.

If radix is undefined, 0 or unspecified and the string does not start with “0x” or “0” then radix 10 is used to parse the given string.

Now, the same symbol can have a different value in different radix system. Let’s understand this by an example. Below is a table of digits and its value in different radix system.

DECIMAL   BINARY    HEXADECIMAL
RADIX=10  RADIX=2   RADIX=160
0         0
1         1         1
2         10        2
3         11        3
4         100       4
5         101       5
6         110       6
7         111       7
8         1000      8
9         1001      9
10        1010      A
11        1011      B
12        1100      C
13        1101      D
14        1110      E
15        1111      F
16        10000     10
17        10001     11

Here you can see 11 has value 3 if the radix is 2 and it has value 17 if the radix is 16.

parseInt - MDN Docs

. . .

Let’s see how map function works

The map() method creates a new array with the results of calling a provided function on every element in the calling array.

var new_array = arr.map(function callback(currentValue[, index[, array]]) { // Return element for new_array }[, thisArg])

It iterates over an array and calls a provided callback function with each element of the array.

Array.prototype.map - MDN Docs

Okay… So map function needs a callback. Just take a guess what will be the output if we give “console.log” function as a callback to map function

[‘1’, ‘5’, ’11’].map(console.log)

Wait before you move forward and just think over it for a second.

If you think this will be the output. Kudos buddy, you are on right track.

Output

But, if you missed this. Don’t worry, here is what happens behind the scene.

As we know map function calls the callback function with three arguments

  1. Current value,
  2. It’s index
  3. And the whole array

So if I simplify the statement it would become

[‘1’, ‘5’, ’11’].map((curr, idx, arr) => console.log(curr, idx, arr))

See, we just simplified the statement and you got your output. Isn’t it easy?

. . .

3 | Try before we move forward

Now, can you try to just combine everything we discussed and use it to get the output of our initial problem case?

Wait again before you move forward. At least give it a shot again. (Try and rewrite our problem statement)

. . .

4 | Final Explanation

If you are getting [1, NaN,3] congrats buddy.

But, if it is still not clicking to you no worries. This is very similar to the console.log problem. We will just rewrite the statement

[‘1’, ‘5’, ’11’].map((curr,idx,arr) => parseInt(curr, idx))

Third argument ignored because parseInt only takes two arguments

Now we will just dry run it and see what will happen with each array element.

1st iteration
curr = ‘1’, idx = 0
parseInt(‘1’, 0) will give 1 as radix is 0.
2nd iteration
curr = ‘1’, idx = 0
parseInt(‘5’, 1) will give NaN as ‘5’ doesn't have value if radix is 1.
3rd iteration
curr = ’11’, idx = 2
parseInt(’11’, 2) will give 3 as ’11’ have value 3 if radix is 2. (Refer to the radix table discussed above)

So, if we combine all this we get the desired output as [1, NaN,3]

. . .

5 | Summary

In short, what is happening here is that map function is passing three arguments to parseInt function but because parseInt can take at most 2 arguments

  1. current element on each iteration
  2. index of the current element

So for the first element ‘1’, parseInt(‘1’, 0) return 1. For the second element ‘5’, parseInt (‘5’, 1) return NaN and for the last element ’11’, parseInt (’11’, 2) returns 3.

That’s why the output was [1, NaN,3].

. . .

5 | What if

Okay, One last question. What if we needed [1, 5, 11] as the output. How should have we modified our statement?

[‘1’, ‘5’, ’11’].map(curr => parseInt(curr))

. . .

Connect with me on LinkedIn or say hi on Twitter, mentioning this article. You can drop a mail at freshrer@gmail.com as well.

Have a wonderful day 🙂