How to transform all strings to numbers in a nested array, except actual strings in Javascript?

Viewed 76

I am trying to transform all values in a 2D array from strings to numbers, except values that are actually strings (within the Javascript Excel Add-in API)

Example:

[["1000"],["3.2"],["banana"]]

to

[[1000],[3.2],["banana]]

"1000" -> 1000
"3.2" -> 3.2
"banana" -> "banana"
4 Answers

You can create a helper function where you use your own rules to determine whether a string is a number or not:

function asNumberIfPossible (str) {
  if (str === '') return str;
  const n = Number(str);
  return Number.isNaN(n) ? str : n;
}

const examples = [
  '1000',
  '3.2',
  'banana',
  '0',
  '',
  '1.2e5',
  '0xfff',
  '0b101',
  ' 0',
  '0 ',
  '0 1',
  '15px',
  '28.5px',
];

for (const str of examples) {
  const result = asNumberIfPossible(str);
  console.log(
    typeof result,
    JSON.stringify(str),
    '->',
    JSON.stringify(result),
  );
}

Note that using the Number() constructor to coerce strings is more strict than using parseInt() or parseFloat(). When using parseFloat(), for example, the string "28.5px" becomes the number 28.5, but using the Number() constructor to coerce the string will result in NaN. This strictness is desirable in my opinion because it prevents a loss of information during the coercion:

const str = '28.5px';

console.log('parseFloat:', parseFloat(str));
console.log('Number:', Number(str));

This function will help you solve the problem:

var values = ['1000','3.2','banana'];

function stringToNumber(arrayOfValues) {
  for (var i = 0; i < arrayOfValues.length; i++) {
    if (typeof arrayOfValues[i] != 'string' || isNaN(arrayOfValues[i])) {
      continue;
    }
    arrayOfValues[i] = +arrayOfValues[i];  // + before a string converts it to number
  }
}

Update:

In the comment below, you wrote you receive a nested array from Excel, so I wrote a recursive function for you:

var arrayOfArrays = [
  ['1000','3.2','banana'], 
  ['2','value','1820','just a word', true], 
  [20]
]; 

var values = ['1000','3.2','banana']; 

function stringToNumber(arrayOfValues) { 
  for (var i = 0; i < arrayOfValues.length; i++) { 
    if (typeof arrayOfValues[i] == 'object') {
      stringToNumber(arrayOfValues[i]); continue;
    }
    if (typeof arrayOfValues[i] != 'string' || isNaN(arrayOfValues[i])) {
      continue;
    }
    arrayOfValues[i] = +arrayOfValues[i]; // + before a string converts it to number
  }
}

Try it out!

Just use the unary plus operator. Any string can be turned into a number using it, as long as the string is exclusively a number.

var x = +”1000”; // results in 1000
var y = +”Hi” // NaN

You can check if the value is greater than -1 and Math.abs to convert the negative to positive, if the condition is true then the value is a number, and if not it's a string.

if(Math.abs(value) > -1) {
    // value is a number
  } else {
    // value is not a number
  }

Related