Разделите числовой массив на куски по 3 с помощью уменьшения - PullRequest
4 голосов
/ 31 мая 2019

Может быть несколько подходов, чтобы решить эту проблему, но я не уверен, почему именно этот не работает должным образом.

[1,2,3,4,5,6,7,8].reduce((a, d, i, c) => [...a, c.splice(0, 3)], [])

Результат - [[1,2,3], [4,5,6]]

Ожидаемый результат - [[1,2,3], [4,5,6], [7,8]]

Пожалуйста, не меняйте подход, так как я хочу знать, почему этот не работает должным образом.

Ответы [ 2 ]

3 голосов
/ 31 мая 2019

Я хочу знать, почему этот работает не так, как ожидалось.

Проблема в том, что вы удаляете записи из исходного массива, поэтому в reduce рано заканчиваются элементы, потому что перед каждым обратным вызовом он проверяет, является ли индекс, который он собирается посетить, все еще меньше, чем длина массива , После второго обратного вызова длина исходного массива равна 2, а индекс равен 2, поэтому reduce останавливается, никогда не создавая третий блок.

Если вы напишите его в более длинной форме, вам будет легче увидеть, что происходит, когда вы проходите через него в отладчике. Вместо того, чтобы записывать видео, я просто наберу код:

[1,2,3,4,5,6,7,8].reduce((a, d, i, c) => {
  console.log("i", i, "c", JSON.stringify(c));
  return [...a, c.splice(0, 3)];
}, []);
.as-console-wrapper {
    max-height: 100% !important;
 }

Как видите, в первом обратном вызове все хорошо:

i 0 c [1,2,3,4,5,6,7,8]

во втором обратном вызове тоже все нормально, но обратите внимание, что c теперь короче:

i 1 c [4,5,6,7,8]

После того, как splice выполнил свою работу в этом втором обратном вызове, c будет [7, 8], поэтому его длина равна 2. reduce на этом останавливается, потому что i теперь 2, и это продолжается только тогда, когда i < length верно. 2 < 2 ложно, поэтому останавливается.

Вы не можете сделать это разумно с reduce. Вместо этого см. Ответы на канонический массив "chunk" . Вы можете сделать это с reduceRight, поскольку Ненад Вракар указывает . (Надеюсь, он / она публикует это как ответ.)

1 голос
/ 31 мая 2019

Это происходит потому, что вы изменяете массив во время итерации. В частности, проблема в том, что когда reduce достигает третьего элемента, остается только два элемента.

[1, 2, 3, 4, 5, 6, 7, 8].reduce((a, d, i, c) => {
  console.log("current result", a)
  console.log("current element", d)
  console.log("index", i)
  console.log("array", c)
  return [...a, c.splice(0, 3)]
}, [])

Итак, когда вы перейдете к третьей итерации, где i должно быть 2, содержимое массива (c) будет [7, 8]. Поскольку это не может работать, третьей итерации не существует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...