简体   繁体   English

虽然循环有两个嵌套的 for 循环输出无限循环,但我做错了什么?

[英]While loop with two nested for loops outputting infinite loop, what am I doing wrong?

I am making a program that takes any random integer add up its individual values and create a sum.我正在制作一个程序,该程序将任意随机的 integer 加起来其各个值并创建一个总和。 If the length of the sum when converted to string form is greater than 1, we continue the process of adding the integer values together until we reach a sum with 1 digit.如果转换为字符串形式后的总和长度大于 1,则继续将 integer 个值相加,直到得到 1 位数的总和。

My issue with the code is that my expected output for random numbers with a value of 1 digit already will return the number immediately, if the numbers with digits greater than 1 add up to another greater than 1 digit number, it will not repeat the loop but rather be stuck in an infinite loop.我的代码问题是我预期的 output 对于值为 1 位的随机数已经会立即返回该数字,如果数字大于 1 的数字加起来是另一个大于 1 位的数字,它不会重复循环而是陷入无限循环。

let digitalRoot = (n) => {
  let stringNum = n.toString();
  let refArr = [];
  let result = 0;
  let iterator = refArr.values();

  while (stringNum.length > 1) {
    
    for (let i = 0; i < stringNum.length; i++) {
      let stringVal = stringNum[i];
      stringVal = parseInt(stringVal);
      refArr.push(stringVal)
    }
    
    for (let number of iterator) {
      if (result !== number) {
        result = result + number;
      }
      else {
        result = result + number;
      }
    }
    
    result = result.toString();
    if (result.length === 1) {
      result = parseInt(result);
      return result;
    }

    refArr = [];
    stringNum = result.toString();

  }

  if (stringNum.length === 1) {
    stringNum = parseInt(stringNum);
    return stringNum;
  }

}

expected output for 1455 , for example, should be 6 , because 1 + 4 + 5 + 5 = 15 ;例如1455的预期 output 应该是6 ,因为1 + 4 + 5 + 5 = 15 1 + 5 = 6 1 + 5 = 6

UPDATE更新

I know my original code in the question was inefficient but I was able to get my intended result by editing a few things, first was moving the refArr & iterator variables into the while loop, resetting the result to 0 and a few other modifications.我知道我在问题中的原始代码效率低下,但我能够通过编辑一些东西来获得预期的结果,首先是将 refArr 和迭代器变量移动到 while 循环中,将结果重置为 0 并进行一些其他修改。 Obviously my code is the very very inefficient solution and isn't recommended but I wanted to correct my code as an exercise, etc.显然我的代码是非常非常低效的解决方案,不推荐使用,但我想将我的代码作为练习等进行更正。

let digitalRoot = (n) => {
  let stringNum = n.toString();
  let result = 0;

  while (stringNum.length > 1) {
    let refArr = [];
    let iterator = refArr.values();

    for (let i = 0; i < stringNum.length; i++) {
      let stringVal = stringNum[i];
      stringVal = parseInt(stringVal);
      refArr.push(stringVal)
    }

    for (let number of iterator) {
      if (result !== number) {
        result = result + number;
      }
      else {
        result = result + number;
      }
    }

    let tester = result.toString();
    if (tester.length === 1) {
      tester = parseInt(tester);
      return tester;
    }

    stringNum = result.toString();
    result = 0;
    refArr = [];
  }

  if (stringNum.length === 1) {
    stringNum = parseInt(stringNum);
    return stringNum;
  }

}

You can do that...你可以这样做...

 const digitalRoot = n => { while (n > 10) n = [...n.toString(10)].reduce((s,v)=>s + +v,0) return n } console.log( digitalRoot( 1455 ))

some points...一些点...

.toString() .toString()
n.toString(10) change 12546 to '12546' n.toString(10)12546更改为'12546'

spread syntax (...) 传播语法 (...)
...'123456' change '12546' to '1','2','3','4','5','6' (iterationnal) ...'123456''12546'更改为'1','2','3','4','5','6' (迭代)
so所以
[...'123456'] make an array = [ '1','2','3','4','5','6' ] [...'123456']创建一个数组 = [ '1','2','3','4','5','6' ]

Array.reduce() 数组.reduce()
and
+v Unary plus (+) just before a string is: as written in the doc: +v字符串前的一元加号 (+)是:如文档中所写:
The unary plus operator (+) precedes its operand and evaluates to its operand but attempts to convert it into a number.一元加号运算符 (+) 在其操作数之前并对其求值,但尝试将其转换为数字。

to explain the reduce method used here:解释这里使用的reduce方法:
[ '1','2','3','4','5','6' ].reduce((s,v) => s + +v, 0)
do:做:

step 0  s =  0, v = '1' ->  0 + +'1' =  0 + 1 = 1 
step 1  s =  1, v = '2' ->  1 + +'2' =  1 + 2 = 3 
step 2  s =  3, v = '3' ->  3 + +'3' =  3 + 3 = 6 
step 3  s =  6, v = '4' ->  3 + +'4' =  6 + 4 = 10 
step 4  s = 10, v = '5' -> 10 + +'5' = 10 + 5 = 15 
step 5  return 15

What happens if n is negative?如果 n 为负数会怎样? Let's assume n >= 0 for this.为此,我们假设 n >= 0。 It's really unclear why you have 2 loops, and the 2nd one has a test for something but does the same thing regardless.真的不清楚为什么你有 2 个循环,而第二个循环对某事进行了测试,但无论如何都做同样的事情。

  • In general, try to avoid making the same variable sometimes a number and sometimes a string.通常,尽量避免使同一个变量有时是数字有时是字符串。 "15" + 1 = "151" while 15 + 1 = 16 "15" + 1 = "151"15 + 1 = 16
  • Reset your accumulators at the start of loops.在循环开始时重置累加器。
  • Rarely a need to grab the iterator before the loop很少需要在循环之前获取迭代器

A simplified version:简化版:

let digitalRoot = (n) => {
  while (n >= 10) {
    // convert to decimal
    let stringNum = n.toString();
    let result = 0
    for (let i = 0; i < stringNum.length; i++) {
      result +=  parseInt(stringNum[i]);
    }
    n = result
  }
  return n
}

Much simpler way would be to use reduce() , this higher function iterates over an array of values and reduces the number of those values with each iteration while calculating the accumulated previous value with the next value in the array.更简单的方法是使用reduce() ,这个更高的 function 迭代一个值数组,并在每次迭代时减少这些值的数量,同时用数组中的下一个值计算累积的前一个值。

Split the string into an array, then map it back to a Number and reduce adding the accumulator to the return value each iteration.将字符串拆分为一个数组,然后 map 将其返回一个数字,并减少每次迭代时将累加器添加到返回值。

 const num = 1455; const num2 = 35714; const num3 = 11211; const sumUp = (num) => { return String(num).split('').map(Number).reduce((a, c) => a + c); } console.log(sumUp(num), sumUp(num2), sumUp(num3))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM