Причина, по которой текущее решение возвращает пустой массив, состоит в том, что вы создаете новый newArr
на каждой итерации. При использовании рекурсии вы должны либо передать результаты при следующем вызове рекурсии, либо объединить результат вызова рекурсии с чем-то в текущем методе.
Без изменения большей части вашего кода следующие изменения устраняют большую часть вашей проблемы :
// move newArr from an inner variable to a parameter
function partsSums(ls, newArr = []) {
if(ls.length == 0){
return newArr;
}
let summedNum = ls.reduce((total, item)=>{
let totalledNum = total + item;
return totalledNum;
})
newArr.push(summedNum);
let [a, ...rest] = ls;
ls = rest;
// pass the current result to next recurring call
return partsSums(ls, newArr)
}
console.log(partsSums([0,1,3,6,10]))
Это не полностью решает вашу проблему, так как вам все еще не хватает значения 0
в результате.
Текущая версия также суммирует содержимое ls
несколько раз, каждая итерация на одну меньше предыдущей. Скажем, я предоставил ls
длины 10. Первая итерация будет go через все 10 элементов и суммировать их (используя reduce
), вторая итерация будет go через 9 элементов и суммировать их, et c . Результат: 10 + 9 + 8 + ... = 55
итераций.
Вместо того, чтобы суммировать все результирующие элементы, сначала получите результат этих элементов. Затем используйте первый элемент результата, так как он содержит самую новую сумму.
Вот 2 примера:
// "normal" recursion
function partsSumsA(ls) {
if (ls.length == 0) return Array.of(0);
const [nr, ...nrs] = ls;
const sums = partsSumsA(nrs);
return [nr + sums[0], ...sums];
}
// tail-recursion
function partsSumsB(ls, sums = Array.of(0)) {
if (ls.length == 0) return sums;
// const [...nrs, nr] = ls;
const nrs = ls.slice(0, -1);
const nr = ls[ls.length - 1];
return partsSumsB(nrs, [nr + sums[0], ...sums]);
}
console.log(...partsSumsA([0,1,3,6,10]));
console.log(...partsSumsB([0,1,3,6,10]));
Для получения дополнительной информации о хвостовой рекурсии см .: Что такое хвостовая рекурсия?