Summing the digits of a number (subtracting the first digit if it is negative)

Posted on

Problem

I’m working on some practice problems using higher- order functions and while I was able to solve this problem. I can’t help but think this code is ugly and not the most eloquent it could be. Is there a way to combined map and reduce is a cleaner way than I have done ? Additionally, is there any other methods or improvements I could have used here ? I’m just looking to get better and any feedback would be appreciated.

Problem: Given a number, “sumDigits” returns the sum of all its digits. If the number is negative, the first digit should count as negative.

function sumDigits(num) {

  //create array of number char
  var string = num.toString().split('');

  //if first char is negative symbol let the first numeric element be negative
  if (string[0] === "-") {
    string[1] = '-' + string[1];
    string.shift();
  }

  //convert string to int
  var toInteger = string.map(function(x) {
    return Number(x);
  });

  //get sum 
  return toInteger.reduce(function(sum, current) {
    sum += current;
    return sum;
  })
}

sumDigits(-316);

Solution

The key to a clean solution is to make it so that the negative sign is not a special case. Instead of splitting the string character-by-character, capture the digits, such that the first digit might be negative.

function sumDigits(num) {
  return num.toString()
            .match(/-?d/g)
            .map(function (s) { return parseInt(s) })
            .reduce(function (a, b) { return a + b });
}

console.log(sumDigits(-316));

Also, your variable names are weird and misleading:

  • The result of .split() is an array, so don’t call it a string.
  • The process of converting a string into a number (i.e. function(x) { return Number(x); }) would be appropriately called toInteger, but once you have applied the string-to-integer conversion to each element of the array, the result would be more appropriately named digits.

Leave a Reply

Your email address will not be published. Required fields are marked *