javascriptsplitparseint

Why parseInt returns different values when apply to array.map


I write a simple function in javascript to parse an IP address string and returns an array of integers that represents four octets:

function parseIP(str) {
  octets = str.split('.');
  console.log(octets);
  return octets.map(parseInt);
}

console.log(parseIP("0.0.0.0"));

To my surprise, the function returns [0, Nan, 0, 0] instead of [0, 0, 0, 0]. Any idea why it behaves this way?


Solution

  • That is a tricky one.

    parseInt takes two parameters, the item and the radix (the number system - 2 for binary, 10 for decimal, 16 for hexadecimal). Your map is feeding it (item,index), because that is how map works

    so you get

    parseInt("0",0); // it seems to default to base 10 but according to the standard it SHOULD return NaN too (a. If R < 2 or R > 36, return NaN.)
    parseInt("0",1); // base 1 NaN because invalid radix since we do not use a "unary" system
    parseInt("0",2); // base 2 binary 0 OK
    parseInt("0",3); // base 3 ternary or trinary 0 OK.
    

    To fix and be sure, use the radix of 10

    const parseIP = (str) => {
      let octets = str.split('.'); // use let, var or const to not pollute the global scope
      return octets.map(str => parseInt(str,10));
    };
    
    console.log(parseIP("0.0.0.0"));
    
    // or use the unary (not the same as te unary number system) plus operator
    
    const parseIP1 = (str) => {
      let octets = str.split('.'); // use let, var or const to not pollute the global scope
      return octets.map(str => +str);
    };
    
    console.log(parseIP1("0.0.0.0"));
    
    // useful for IP string comparing:
    
    const padIP = (str) => {
      let octets = str.split('.'); // use let, var or const to not pollute the global scope
      return octets.map(str => str.trim().padStart(3,'0')).join('.');
    };
    
    console.log(padIP("1.255.3.10"));