Я работал над ката от Codewars, задача состоит в том, чтобы написать функцию, постоянство, которая принимает положительный параметр num и возвращает его мультипликативную постоянство, то есть количество раз, которое вы должны умножить цифры в num, пока не достигнете одна цифра.
Пример:
persistence(39) === 3 // because 3*9 = 27, 2*7 = 14, 1*4=4
// and 4 has only one digit
persistence(999) === 4 // because 9*9*9 = 729, 7*2*9 = 126,
// 1*2*6 = 12, and finally 1*2 = 2
persistence(4) === 0 // because 4 is already a one-digit number
Пытаясь понять это, я наткнулся на решение в Интернете (показано ниже), и после попытки понять его логику я не мог понять, почему код не работает.
var count = 0;
function persistence(num) {
if (num.toString().length === 1) {
return count;
}
count++;
var mult = 1;
var splitStr = num.toString().split("");
for (var i = 0; i <= splitStr; i++) {
mult *= parseFloat(splitStr[i])
}
return persistence(parseFloat(mult));
}
Вывод для любого однозначного числа будет 0, что является правильным, однако для любого числа, состоящего из нескольких цифр, постоянство всегда регистрируется как 1, и я не могу понять, почему, любая помощь будет принята с благодарностью.
Кроме того, опубликованный код приводит к чему-то другому, поскольку count устанавливается на 0 только при первом запуске...
Вторая функция плохая, она зависит от глобальной переменной count, поэтому дает разный результат в зависимости от того, когда она была вызвана. Его следует переписать на return 0 и return 1 + persistence(...) и вообще не использовать глобальное count.
@HereticMonkey Извините, я разместил неправильный фрагмент кода, но теперь удалил его, так как понимаю, почему это может сбивать с толку.
@ user633183 ОП знает, как решить проблему; они специально спрашивают, почему размещенный код не работает.
@MattBurland Извините за это, я искал первоисточник и понял, что он был на coderbyte, поэтому я соответствующим образом отредактировал свой пост (не уверен, что вы можете сделать ссылку вне переполнения стека). Я пытаюсь понять, почему код не работает, поскольку я прочитал его и не уверен, в чем именно заключается проблема.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Опубликованный код имеет довольно много проблем.
for (var i = 0; i <= splitStr; i++) {
Но splitStr — это массив, а не число; i <= splitStr не имеет смысла. Он должен проверяться на splitStr.length вместо splitStr.
Другая проблема заключается в том, что он должен использовать i <, а не i <=, иначе окончательный splitStr[i] будет undefined.
Другая проблема заключается в том, что переменная count является глобальной, поэтому более чем один вызов persistence приведет к неточным результатам. Переменная count вообще не нужна. Починить это:
function persistence(num) {
if (num.toString().length === 1) {
return 0;
}
var mult = 1;
var splitStr = num.toString().split("");
for (var i = 0; i < splitStr.length; i++) {
mult *= parseFloat(splitStr[i])
}
return 1 + persistence(parseFloat(mult));
}
console.info(
persistence(999),
persistence(39),
persistence(4)
);Или можно полностью избежать цикла for и использовать более подходящие методы массива:
function persistence(num) {
const str = num.toString();
if (str.length === 1) {
return 0;
}
const nextNum = str.split('').reduce((a, b) => a * b, 1);
return 1 + persistence(nextNum);
}
console.info(
persistence(999),
persistence(39),
persistence(4)
);const persistence=(num)=>{
let splitNumArr=num.toString().split('')
let newList
let count=0
while(splitNumArr.length>1){
newList=splitNumArr.reduce((acc,curr)=>{
return acc*=curr
})
splitNumArr=newList.toString().split('')
count++
}
return count
}
console.info(persistence(39))===3
console.info(persistence(999))===4
console.info(persistence(9))===0
Если вы спрашиваете, почему вторая часть кода работает именно так, лучше не запутывать проблему, показывая другой код. Кроме того, оба фрагмента кода используют цикл
forи не отображаютwhile....