recursion - How to sum digits recursively javascript - Stack Overflow

I'm learning the basics of JavaScript and am trying to write a recursive function to add together

I'm learning the basics of JavaScript and am trying to write a recursive function to add together a group of integers. For example, the function argument would be 1234 and the result should be 10. Here's what I have so far...

function sumDigits(numbersStr) {

  var numToString = numbersStr.toString()
  var numArr = numToString.split('').map(Number);

  var sum = 0;

  // base case
  if (numArr.length === 0) {
    return sum
  } 

  // recursive case
  else {
    var popped = numArr.pop();
    sum+=popped;
    return sumDigits(numArr);

  }
}

But I get an infinite loop whenever I run this (my tab crashes). If I'm popping the last element of an array, adding it to the sum variable, then calling the function again on the shortened array, then why do I get an infinite loop? Many thanks!

I'm learning the basics of JavaScript and am trying to write a recursive function to add together a group of integers. For example, the function argument would be 1234 and the result should be 10. Here's what I have so far...

function sumDigits(numbersStr) {

  var numToString = numbersStr.toString()
  var numArr = numToString.split('').map(Number);

  var sum = 0;

  // base case
  if (numArr.length === 0) {
    return sum
  } 

  // recursive case
  else {
    var popped = numArr.pop();
    sum+=popped;
    return sumDigits(numArr);

  }
}

But I get an infinite loop whenever I run this (my tab crashes). If I'm popping the last element of an array, adding it to the sum variable, then calling the function again on the shortened array, then why do I get an infinite loop? Many thanks!

Share Improve this question edited Feb 20, 2018 at 20:48 e1v1s asked Feb 20, 2018 at 20:41 e1v1se1v1s 3858 silver badges22 bronze badges 11
  • And what did you try to debug?did you try to alert some values – Pierre Commented Feb 20, 2018 at 20:42
  • 1 console.log is a preferred means of debugging code. Or, use a breakpoint and step through line by line. – user47589 Commented Feb 20, 2018 at 20:43
  • 1 It doesn't make any sense; sumDigits doesn't take an array. If you want to use an array you need a function that takes an array and an accumulator. – Dave Newton Commented Feb 20, 2018 at 20:43
  • Definitely a lack of debugging... – Pierre Commented Feb 20, 2018 at 20:44
  • 1 @Amy 1234 is a single number; it's only later that it's conflated with an array of numbers, which also wouldn't be numbersStr :/ – Dave Newton Commented Feb 20, 2018 at 20:45
 |  Show 6 more ments

8 Answers 8

Reset to default 3

The problem in your code is that sumDigits expects to get a number, but in the recursion you pass an array of numbers to it.

You could use a string or number as argument of the function and convert the value to a string.

Then check the length and return zero if the length is zero (usualy the exit condition).

If not return the value of the fist character and add the result of calling the function with a sliced string from index one.

Basically a recurisve function have two parts.

  1. The exit condition with an exit value. This depends on the purpose of the recursive function. It is usually a neutral value, like zero for addition, or 1 for multiplication.

  2. The actuall value plue a arithmetic operation and the call of the function again with a reduced string/array or numerical value.

function sumDigits(num) {
    num = num.toString();
    return num.length === 0
        ? 0
        : +num[0] + sumDigits(num.slice(1));			
}

console.log(sumDigits(1234));

Another approach would be the use of tail recursion, which does not extend the stack for each calling function, because the function ends with the call without keeping a temporary value liek in above function, the actual numerical value +num[0] and the waiting for execution of the adition.

In this case, you could store the intermediate result along with the calling of the function.

function sumDigits(num, sum) { // num is expected to be a string
    sum = sum || 0;
    if (num.length === 0) {
        return sum;
    }
    return sumDigits(num.slice(1), sum + +num[0]);
}

console.log(sumDigits('1234'));

function digitCount(num) {
     let val1 = num % 10
let rem = Math.floor(num / 10)
return val1 + (rem != 0 ? digitCount(rem) : 0)
}

console.log(digitCount(87))

The problem is that your function takes a number as it's argument, but when you use it recursively, you're giving it an array back. I would remend pulling the recursive part into its own helper function like so:

function sumDigits(num) {

  var numStr = num.toString()
  var numArr = numStr.split('').map(Number);

  function sumHelper(arr) {
    // Base case:
    if (arr.length === 1) {
      return arr[0];
    }

    // Otherwise recurse (return last number plus the sum
    // of the remainder):
    return arr.pop() + sumHelper(arr);
  }

  // Then use that recursive helper:
  return sumHelper(numArr);
}

console.log(sumDigits(1234))

Your function expects a string, but on the recursive call, you pass it an array.

Additionally, you've got a call to .map that isn't needed because you can convert the strings in the .split array to numbers simply by prepending a + to them.

Is there any reason you just don't use Array.reduce?

function sumDigits(stringOfNums) {
  // Split the string into an array of strings. Reduce the array to the sum by 
  // converting each string to a number.
  console.log(stringOfNums.split('').reduce(function(x,y){ return +x + +y}, 0));
}
sumDigits("1234");

Passing an array in the recursive call will guarantee that its .toString() will never be empty because the mas will add more characters than have been removed.

Instead, do it mathematically so you don't need an array or even string conversion.

function sumDigits(num) {
  return num ? (num%10) + sumDigits(Math.floor(num/10)) : 0
}

console.log(sumDigits(1234))

This assumes a positive integer is passed. You'll need additional guards if other input could be provided.

There's no need to convert the number to an array. You can get the last digit of a number with number % 10, and remove that digit with Math.floor(number / 10). Then recurse until the number is 0.

function sumDigits(num) {
  if (num == 0) {
    return 0;
  } else {
    var last = num % 10;
    var rest = Math.floor(num / 10);
    return last + sumDigits(rest);
  }
}
console.log(sumDigits(1234));

Barmar has a good voice of reason. Converting from number to string then converting back to number again is a bit silly. Plus, if this is a homework assignment, using high-level functions like String.prototype.split probably won't teach you much.

Here's a tail-recursive version Barmar's program written using functional style

  • base case - the input number n is zero, return the accumulator acc
  • inductive case - n is not zero; recur with the next n and the next acc

const sumDigits = (n = 0, acc = 0) =>
  n === 0
    ? acc
    : sumDigits (n / 10 >> 0, acc + n % 10)

console.log (sumDigits ())     // 0
console.log (sumDigits (1))    // 1
console.log (sumDigits (12))   // 3
console.log (sumDigits (123))  // 6
console.log (sumDigits (1234)) // 10

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745049164a4608278.html

相关推荐

  • recursion - How to sum digits recursively javascript - Stack Overflow

    I'm learning the basics of JavaScript and am trying to write a recursive function to add together

    7小时前
    40

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信