Javascript Array.reduce () разбивает страницу с кодом ошибки 6

Веб-страница работает нормально, пока я не передаю начальное значение, но в этом случае она просто дает мне TypeError, потому что когда есть только последний элемент (как и ожидалось). Вот почему я пытаюсь передать 0 в качестве начального значения функции уменьшения (строка 4 нижеприведенного фрагмента). Но как только я это сделаю, он просто разбивает всю страницу с кодом ошибки 6.

Чего я пытаюсь достичь: я складываю сумму всех элементов массива, затем помещаю эту сумму в другой массив, удаляю первый элемент и повторяю процесс. Когда не осталось элементов, я хочу вернуть 0 из функции reduce (), поэтому я пытаюсь передать начальное значение (0).

function partsSums(ls) {
  let sumArr = [];
  while (ls.length >= 0) {
    sumArr.push(ls.reduce((acc, cur) => acc + cur, 0));
    ls.shift();
  }
  return sumArr;
}

partsSums([0, 1, 3, 6, 10]);

Результат, который я ищу: [20, 20, 19, 16, 10, 0]

Скриншот ошибки


person Link    schedule 22.10.2020    source источник
comment
Измените ls.length >= 0 на ls.length > 0. Условие для цикла while никогда не будет оцениваться как ложное, поскольку длина массива никогда не будет меньше 0, поэтому у вас есть бесконечный цикл.   -  person Jon Warren    schedule 22.10.2020
comment
какой результат вы ищете?   -  person mr hr    schedule 22.10.2020
comment
Я хочу вставить 0 в свой sumArr, когда в массиве ls, для которого я вызываю функцию reduce () fn, не осталось элементов. если я установил ls.length на ›0, то он просто остановится после последнего элемента. Я могу нажать 0 после функции reduce () fn, но есть ли способ сделать это с помощью функции сокращения?   -  person Link    schedule 22.10.2020
comment
Результат, который я ищу: [20, 20, 19, 16, 10, 0]   -  person Link    schedule 22.10.2020
comment
@Link Вы можете просто добавить sumArr.push(0) после цикла while.   -  person 3limin4t0r    schedule 22.10.2020
comment
@ 3limin4t0r да, но я просто хотел посмотреть, есть ли способ сделать это без явного добавления этого элемента (0) в мой массив.   -  person Link    schedule 22.10.2020


Ответы (3)


Вы можете сделать это:

function partsSums(ls)
  {
  let sumArr = []
    , lng    = ls.length
    ;
  while ( lng >= 0)
    {
    sumArr.push(ls.reduce((acc, cur) => acc + cur, 0))
    ls.shift()
    --lng
    }
  return sumArr
  }

console.log(JSON.stringify( partsSums([0, 1, 3, 6, 10])  ))
.as-console-wrapper { max-height: 100% !important; top: 0; }

person Mister Jojo    schedule 22.10.2020
comment
Спасибо! Это именно то, что я искал. Мне тоже следовало сократить длину. Виноват. Большое спасибо @Mister Jojo - person Link; 22.10.2020

Проблема с вашим кодом - это условие ls.length >= 0. Это условие приводит к бесконечному циклу. Измените его на ls.length > 0

Предположение

Кажется, вы ищете кумулятивное суммирование справа налево. Но ваша функция нерентабельна. Вы можете использовать suffix-sum для этой проблемы.

const suffixSum = arr => {
  const res = [];
  const {length} = arr;
  res[length] = 0;

  for (let i = length - 1; i >= 0; i--) {
    res[i] = res[i+1] + arr[i];
  }
  
  return res;
}

console.log(suffixSum([0, 1, 3, 6, 10]));

Этот алгоритм занимает O(n) времени, а ваш алгоритм занимает O(n^2) времени.

person Sajeeb Ahamed    schedule 22.10.2020
comment
Спасибо за ответ, но я просто пытался узнать, как использовать функцию Array.prototype.reduce () fn. Вы хотите сказать, что моя веб-страница не работает из-за того, что моя функция не рентабельна? - person Link; 22.10.2020
comment
Неа! решение вашей проблемы находится в разделе комментариев. Это просто из-за ls.length >= 0. Это заставляет вас зацикливаться. - person Sajeeb Ahamed; 22.10.2020
comment
Я просто поделюсь хорошим решением второй части вашего вопроса Чего я пытаюсь достичь. - person Sajeeb Ahamed; 22.10.2020
comment
Спасибо, но это все еще не решает мою проблему, потому что я хочу добавить 0 в конец массива результатов перед его возвратом и пытался сделать это в функции Array.prototype.reduce (). - person Link; 22.10.2020

Как упоминалось в комментариях, вы получаете бесконечный цикл, потому что длина массива никогда не будет меньше 0.

Как показано в других ответах, вы можете решить это, изменив условие на ls.length > 0, но тогда вы не получите конечный случай нажатия 0 в результат на последней итерации, когда массив пуст.

Вместо того, чтобы проверять длину в условии while(), проверьте его после вызова reduce(), а затем выйдите из цикла.

function partsSums(ls) {
  let sumArr = [];
  while (true) {
    sumArr.push(ls.reduce((acc, cur) => acc + cur, 0));
    if (ls.length == 0) {
      break;
    }
    ls.shift();
  }
  return sumArr;
}

console.log(partsSums([0, 1, 3, 6, 10]));

person Barmar    schedule 22.10.2020