Search code examples
javascriptarraysforeacharray-splice

My function to remove even values from an array is still returning an even number


I am trying to remove even integers from an array. The function I wrote is still returning an index with an even number in it. I'm not sure why I'm getting that kind of behavior. Any thoughts?

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]

Solution

  • Don't splice an array while iterating over it - that'll change it in place. For example, if you start with an array [2, 4, 6], and on the first iteration, remove the item at index 0, the array will then be [4, 6], and you'll go onto the second iteration, where i is 1. You'll then remove the item at the 1st index, which is 6, resulting in the array becoming [4].

    Every time an item gets removed, your current method forgets to re-check the new item that fell into the index of the removed item.

    It's very confusing. Either use a for loop and start at the end of the array instead, or (even better) use .filter:

    let arr = [6, 3, 19, 43, 12, 66, 43];
    
    const removeEvenValues = arr => arr.filter(num => num % 2 !== 0);
    
    console.log(removeEvenValues(arr)); 

    If you have to mutate the existing array (which usually isn't a good idea unless absolutely necessary), then:

    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));