Почему цикл javascript forEach не выполняет итерацию полного массива со сращиванием - PullRequest
0 голосов
/ 24 октября 2019

Я играл с javascript .splice() и .forEach() методами, код работает нормально, но он не выдает ожидаемого результата.

проблема в том, что .forEach() работает для половины массива изатем выходит.

то, что я ожидаю, будет:

[['Apple'],['Banana'],['Mango'],['Pomegranate']]

Но вывод

[['Apple'],['Banana']]

Я не могу понять, почему он ведет себя какэто. из mdn

говорится, что метод .splice() обновляет свойство длины массива. тогда он должен работать нормально.

Есть ли способ заставить его работать так, как ожидалось.

По какой-то причине я просто не хочу использовать .map() или любые другие функции.

const fruits = ['Apple', 'Banana', 'Mango', 'Pomegranate']
const fruitsList = []

function removeArrayItem(item,index){
    let fruit = fruits.splice(0,1)
    fruitsList.push(fruit)
}

fruits.forEach(removeArrayItem)
console.log(fruitsList)

Ответы [ 3 ]

0 голосов
/ 24 октября 2019

Splice изменяет исходный массив.

Метод splice () изменяет содержимое массива, удаляя или заменяя существующие элементы и / или добавляя новые элементы на месте.

Источник: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice

Это означает, что когда splice() применяется к массиву, который перебирает forEach(), он модифицируется (становится короче), поэтому у него нет элементов для переборачерез некоторое время.

0 голосов
/ 24 октября 2019

Вы изменяете исходный массив неправильно, если после каждой итерации вы видите массив, который удален из фруктов, и вы помещаете этот массив в новый список.

При таком подходевы не будете изменять индексы во время мутации сплайсинга.

const fruits = ['Apple', 'Banana', 'Mango', 'Pomegranate']
const fruitsList = []

function removeArrayItem(item,index){
    let fruit = fruits.splice(index,1,'')
    fruitsList.push(fruit)
}

fruits.forEach(removeArrayItem)
console.log(fruitsList)

https://codepen.io/psyNiiM/pen/JjjNRaJT

0 голосов
/ 24 октября 2019

Как довольно четко описано в документации MDN , метод .forEach() определяет элементы, которые будут задействованы в итерации до ее запуска.

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

Кроме того, ваш код написан так, что обратный вызов .forEach() игнорирует его аргументы. ,Он всегда просто удаляет первый элемент массива fruits. Таким образом, на первой итерации вы получаете «Apple», а массив теперь состоит всего из трех элементов. Следующим итерированным элементом будет «Mango», а не «Banana», но поскольку код не обращает внимания на item, вы получаете новый первый элемент исходного массива. После этого в массиве есть только два элемента, поэтому итерация заканчивается.

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

const fruits = ['Apple', 'Banana', 'Mango', 'Pomegranate']
const fruitsList = []

for (let index = 0, len = fruits.length; index < len; index++) {
  if (index in fruits) {
      let fruit = fruits.splice(0,1)
      fruitsList.push(fruit)
  }
}

Тест if в этом цикле иллюстрирует важное поведение .forEach(): он пропускает пустые индексы массива (то есть, которые никогда не были инициализированы значением). Вызовы .slice() удаляют элемент из fruits, поэтому после первых двух итераций он даже не будет пытаться выполнить больше .slice() вызовов, потому что индексы 2 и 3 будут пустыми.

правильный способ сделать это, если бы это был реальный код, был бы

const fruits = ['Apple', 'Banana', 'Mango', 'Pomegranate']
const fruitsList = fruits.map(function(fruit) {
  return [fruit];
});
fruits = []; // if you really want to empty it out

(а функция => была бы еще более краткой).

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