Моя функция удаления четных значений из массива по-прежнему возвращает четное число - PullRequest
1 голос
/ 03 ноября 2019

Я пытаюсь удалить четные числа из массива. Функция, которую я написал, все еще возвращает индекс с четным числом в нем. Я не уверен, почему у меня такое поведение. Есть мысли?

let arr = [6, 3, 19, 43, 12, 66, 43];

const removeEvenValues = arr => {
  arr.forEach((num, i) => {
    if(num % 2 === 0) arr.splice(i, 1);
  });
};

removeEvenValues(arr); // arr becomes [3, 19, 43, 66, 43] but should become [3, 19, 43, 43]

Ответы [ 2 ]

2 голосов
/ 03 ноября 2019

Не splice массив во время итерации по нему - это изменит его вместо . Например, если вы начнете с массива [2, 4, 6] и на первой итерации удалите элемент с индексом 0, тогда массив будет [4, 6], и вы перейдете ко второй итерации, где i1. Затем вы удалите элемент по первому индексу, который равен 6, в результате чего массив станет [4].

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

Это очень запутанно. Либо используйте цикл for и начинайте с end массива, либо (еще лучше) используйте .filter:

let arr = [6, 3, 19, 43, 12, 66, 43];

const removeEvenValues = arr => arr.filter(num => num % 2 !== 0);

console.log(removeEvenValues(arr)); 

Если у вас есть для изменения существующего массива (что обычно не является хорошей идеей, если в этом нет крайней необходимости), тогда:

let arr = [6, 3, 19, 43, 12, 66, 43];

const removeEvenValues = arr => {
  for (let i = arr.length - 1; i >=0; i--) {
    if (arr[i] % 2 === 0) {
      arr.splice(i, 1);
    }
  }
  return arr;
}

console.log(removeEvenValues(arr));
0 голосов
/ 03 ноября 2019

При объединении массива вы изменяете массив, поэтому, когда у вас есть два, даже подряд, второй пропускается после того, как первый соединен

Теперь, предполагая, что вам нужно изменить массиввместо того, чтобы создавать новый массив, у вас есть две опции

Наиболее распространенная, для обработки массива от конца к началу, таким образом, мутации не путают, какой элемент вашей обработки

let arr = [6, 3, 19, 43, 12, 66, 43];

const removeEvenValues = arr => {
  for (let i = arr.length - 1; i >= 0; --i) {
    if(arr[i] % 2 === 0) arr.splice(i, 1);
  };
};

removeEvenValues(arr);
console.log(arr);

Или, если вы хотите (неправильно) использовать метод массива - так как reduRight обрабатывает массив от конца к началу, вы можете использовать его как forEach (просто игнорируйтеаргумент «аккумулятор», и убедитесь, что вы инициализируете его (это то, что является нулем)

let arr = [6, 3, 19, 43, 12, 66, 43];

const removeEvenValues = arr => {
  arr.reduceRight((_, num, i) => {
    if(num % 2 === 0) arr.splice(i, 1);
  }, null);
};

removeEvenValues(arr);
console.log(arr);
...