Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

array.splice removing values from remaining elements

I ran across this strange side effect of array.splice, and distilled the code down to the minimum necessary to recreate. Yes, much of this could be done on one line with array.filter, but I'm interested in whether I've made a mistake or if something else is going on.

var array = [];

for (var i = 0; i < 10; i++) {
  array.push({
    value: i
  });
}

array.forEach(function(item, index, intArray) {
  if (item.value % 2 == 1) {
    item.odd = true;
  } else {
    item.odd = false;
  }

  if (item.odd) {
    console.log("Removing " + item.value);
    intArray.splice(index, 1);
  }

});

console.log(array);

Running this javascript results in the odd elements being removed as expected, but it also removed the item.odd values for items 2, 4, 6, and 8. Removing the intArray.splice line brings back the odd array elements, but it also brings back the item.odd values for all elements.

I've tested this in FF and Chrome. The behavior persists even if only the item is passed into the callback, with the index calculated via array.indexOf, and referencing the array from outside the loop.

like image 778
Brian Bauman Avatar asked Jan 21 '16 19:01

Brian Bauman


People also ask

How do you remove an element from an array using splice?

The splice() function changes the contents of an array by removing existing elements and/or adding new elements. In splice the second argument is the number of elements to remove. splice modifies the array in place and returns a new array containing the elements that have been removed.

How do you remove values from an array?

Find the index of the array element you want to remove using indexOf , and then remove that index with splice . The splice() method changes the contents of an array by removing existing elements and/or adding new elements. The second parameter of splice is the number of elements to remove.

Does splice returns removed element?

splice() JS Array Method. The splice() method is a built-in method for JavaScript Array objects. It lets you change the content of your array by removing or replacing existing elements with new ones. This method modifies the original array and returns the removed elements as a new array.

How do you remove an element from the end of an array?

Using the Array pop() Method The Array pop() method is the simplest method used to remove the last element in an array. The pop() method returns the removed element from the original array.


1 Answers

I think that when you splice the array at every odd number, the forEach ends up skipping over the next item, which is an even number. So those items don't get modified at all.

var array = [];

for (var i = 0; i < 10; i++) {
  array.push({
    value: i
  });
}

array.forEach(function(item, index, intArray) {
  console.log(item); // only prints out 0, 1, 3, 5, 7, 9

  if (item.value % 2 == 1) {
    item.odd = true;
  } else {
    item.odd = false;
  }

  if (item.odd) {
    console.log("Removing " + item.value);
    intArray.splice(index, 1);
  }

});

console.log(array);

In other words, forEach only visits each index once. So say it gets to item 1, which is at index 1. It deletes item 1. Item 2 is now at index 1. But index 1 has already been visited, so it moves on to the item at index 2, which is now item 3.

like image 180
chinaowl Avatar answered Oct 12 '22 10:10

chinaowl