无法在JS的“ while循环”中检测到无限循环的原因

时间:2019-05-25 10:02:24

标签: javascript loops while-loop infinite-loop

我的while循环中有一个无限循环,我找不到原因。

这是一个简单函数,可返回参数位数的总和。我使用while循环,因为它需要加总数字,直到它降到一个数字为止。 我确保添加了一条语句,以确保在某个时刻循环会中断。,但是显然不会。

function digital_root(n) {
 num = n;
 sum = 0;
 while (num.toString().length>1){
      for (i=0; i<num.toString().length; i++) {
           sum += parseInt(num.toString()[i])    
       }
       num = sum;
  }
  return sum;
}
digital_root(456)

我收到一条警告,说我在第4行有一个无限循环(while循环)。 我希望num=sum将新的整数(位数减少)分配给num变量,从而在某个时候脱离循环。这是错吗?

更让我感到困惑的是,我用来调试问题的大多数JS编辑器都会返回输出,但这需要花费很多时间。那是无限循环吗?

4 个答案:

答案 0 :(得分:4)

您有一个嵌套循环结构,其中第一个条件始终为真。

要只获取10以下的数字,可以再次调用该函数作为递归。

function digital_root(n) {
    var num = n.toString(), // declare and use the string value
        sum = 0,
        i;

    for (i = 0; i < num.length; i++) {
        sum += parseInt(num[i], 10)
    }
    return sum > 9
        ? digital_root(sum)
        : sum;
}

console.log(digital_root(456));

答案 1 :(得分:1)

重新阅读问题后,我注意到您正在尝试将整数缩减为单个数字。您的代码存在的问题是0仅在 while 循环之前设置为sum = 0。这意味着它没有在第二,第三,...运行时重置。

function digital_root(n) { var num, sum, i; num = n; while (num.toString().length > 1) { sum = 0; for (i = 0; i < num.toString().length; i++) { sum += parseInt(num.toString()[i]); } num = sum; } return sum; } console.log(digital_root(456));移入while循环可解决此问题。我还在顶部添加了变量声明,以避免设置全局变量。

function digital_root(integer) {
  // guard against things that might result in an infinit loop, like floats
  if (!Number.isInteger(integer) || integer < 0) return;
  
  const chars = integer.toString().split("");
  if (chars.length == 1) return integer;
  
  return digital_root(
    chars.map(char => parseInt(char))
         .reduce((sum, digit) => sum + digit)
  );
}

console.log(digital_root(456));

此处以递归方式编写,我个人更喜欢这种样式:

Character

答案 2 :(得分:0)

既然您已经有了答案,那么这是获得结果的另一种方法

function digital_root(n) {
  // convert the number to string
  // use split to create an array of number viz ['4','5','6']
  // use reduce to sum the number after converting to number
  // 0 is the initial value
  return n.toString().split('').reduce((a, c) => a + parseInt(c, 10), 0)
}
console.log(digital_root(456))

答案 3 :(得分:0)

避免所有导致您所面临的情况的嵌套循环,我宁愿以一种更具可读性的方式进行操作。

function digital_root(n) {
    sum = n;

    while(sum.toString().length > 1) {
        sum = sum.toString()
       .split('')
       .map(digit => parseInt(digit, 10))
       .reduce((acc, cur) => acc + cur);
    }

    return sum;
}

console.log(digital_root(456));