[英]While loop with two nested for loops outputting infinite loop, what am I doing wrong?
我正在制作一个程序,该程序将任意随机的 integer 加起来其各个值并创建一个总和。 如果转换为字符串形式后的总和长度大于 1,则继续将 integer 个值相加,直到得到 1 位数的总和。
我的代码问题是我预期的 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;
}
}
例如1455
的预期 output 应该是6
,因为1
+ 4
+ 5
+ 5
= 15
; 1
+ 5
= 6
更新
我知道我在问题中的原始代码效率低下,但我能够通过编辑一些东西来获得预期的结果,首先是将 refArr 和迭代器变量移动到 while 循环中,将结果重置为 0 并进行一些其他修改。 显然我的代码是非常非常低效的解决方案,不推荐使用,但我想将我的代码作为练习等进行更正。
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;
}
}
你可以这样做...
const digitalRoot = n => { while (n > 10) n = [...n.toString(10)].reduce((s,v)=>s + +v,0) return n } console.log( digitalRoot( 1455 ))
一些点...
.toString()
n.toString(10)
将12546
更改为'12546'
传播语法 (...)
...'123456'
将'12546'
更改为'1','2','3','4','5','6'
(迭代)
所以
[...'123456']
创建一个数组 = [ '1','2','3','4','5','6' ]
数组.reduce()
和
+v
字符串前的一元加号 (+)是:如文档中所写:
一元加号运算符 (+) 在其操作数之前并对其求值,但尝试将其转换为数字。
解释这里使用的reduce方法:
[ '1','2','3','4','5','6' ].reduce((s,v) => s + +v, 0)
做:
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
如果 n 为负数会怎样? 为此,我们假设 n >= 0。 真的不清楚为什么你有 2 个循环,而第二个循环对某事进行了测试,但无论如何都做同样的事情。
"15" + 1 = "151"
而15 + 1 = 16
简化版:
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
}
更简单的方法是使用reduce()
,这个更高的 function 迭代一个值数组,并在每次迭代时减少这些值的数量,同时用数组中的下一个值计算累积的前一个值。
将字符串拆分为一个数组,然后 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.