Как сохранить значение массива в рекурсии?
Решаю задачу на codewars и не могу понять в чем проблема.
Задача следующая: написать функцию, которая будет принимать число и каждую его единицу будет перемножать и записывать промежуточный результат в массив.
Пример:
per(1) //вернет []
per(10) //1*0 вернет 0
per(69) //6*9 = 54, 5*4 = 20, 2*0 = 0 .Вернет [54, 20, 0])
per(277777788888899) // Вернет [4996238671872, 438939648, 4478976, 338688, 27648, 2688, 768, 336, 54, 20, 0])
Сделал так
var out = [];
function per(n) {
let arr = n.toString().split("");
let res = arr[0];
if (arr.length == 1) {
return [];
}
for (let i = 1; i < arr.length; i++) {
res *= arr[i];
}
out.push(res);
per(res);
return out;
}
console.log(per(69));
Если проверять через консоль, то все работает и результаты правильные. Если проверять на codewars, то он ругается на код при проверке со следующими входными данными:
per(69) // почему-то возвращает [0, 54, 20, 0] вместо [54, 20, 0]
per(277777788888899)
//возвращает
[0, 54, 20, 0, 4996238671872, 438939648, 4478976, 338688, 27648, 2688, 768, 336, 54, 20, 0]
вместо
[4996238671872, 438939648, 4478976, 338688, 27648, 2688, 768, 336, 54, 20, 0],
У меня есть подозрение, что я ломаю проверку на codewars своей глобальной переменной, куда записываю промежуточный результат. Но знаний не хватает. Не понимаю как внутри рекурсии сохранить значения в массиве out
Ответы (2 шт):
Можно обернуть весь код еще в одну функцию, тогда массив будет уже не глобальным. Можно передавать массив вторым параметром, вообще избавившись от глобальной переменной
Можно передавать массив вторым аргументом. При первом вызове он не будет определен - ничего страшного, можно сделать значение по умолчанию - []
console.log( per(1) );
console.log( per(10) );
console.log( per(69) );
console.log( per(277777788888899) );
function per(n, arr = []) {
// Только у первого вызова не будет arr: Станет []
if (n < 10) return arr;
let mul = ("" + n).split("").reduce((res, digit) => res * digit);
// Результат умножения цифр
arr.push(mul);
return per(mul, arr); // Все последующие вызовы уже со вторым аргументом - массивом.
}
И без рекурсии:
console.log( per(1) );
console.log( per(10) );
console.log( per(69) );
console.log( per(277777788888899) );
function per(n) {
let arr = [];
while (n > 9) {
n = ("" + n).split("").reduce((res, digit) => res * digit);
arr.push( n );
}
return arr;
}
Но на codewars любят заниматься хе спортивным сокращением кода...
let per = (n, a = []) => {
while (n > 9) a.push( n = ("" + n).split("").reduce((r, d) => r * d) )
return a
}
console.log( per(1) );
console.log( per(10) );
console.log( per(69) );
console.log( per(277777788888899) );
Кажется короче некуда)
Если не рассматривать while (n > 9) a.push( n = eval(("" + n).split("").join("*")) )