Loop to remove an element in array with multiple occurrences

That is because the for-loop goes to the next item after the occurrence is deleted, thereby skipping the item directly after that one.

For example, lets assume item1 needs to be deleted in this array (note that <- is the index of the loop):

item1 (<-), item2, item3

after deleting:

item2 (<-), item3

and after index is updated (as the loop was finished)

item2, item3 (<-)

So you can see item2 is skipped and thus not checked!

Therefore you'd need to compensate for this by manually reducing the index by 1, as shown here:

function removeItem(item){
    for(var i = 0; i < array.length; i++){
        if(array[i]==item) {
            array.splice(i,1);
            i--; // Prevent skipping an item
        }
    }
}

Instead of using this for-loop, you can use more 'modern' methods to filter out unwanted items as shown in the other answer by Benjamin.


None of these answers are very optimal. The accepted answer with the filter will result in a new instance of an array. The answer with the second most votes, the for loop that takes a step back on every splice, is unnecessarily complex.

If you want to do the for loop loop approach, just count backward down to 0.

for (var i = array.length - 0; i >= 0; i--) {
  if (array[i] === item) {
    array.splice(i, 1);
  }
}

However, I've used a surprisingly fast method with a while loop and indexOf:

var itemIndex = 0;
while ((itemIndex = valuesArray.indexOf(findItem, itemIndex)) > -1) {
  valuesArray.splice(itemIndex, 1);
}

What makes this method not repetitive is that after the any removal, the next search will start at the index of the next element after the removed item. That's because you can pass a starting index into indexOf as the second parameter.

In a jsPerf test case comparing the two above methods and the accepted filter method, the indexOf routinely finished first on Firefox and Chrome, and was second on IE. The filter method was always slower by a wide margin.

Conclusion: Either reverse for loop are a while with indexOf are currently the best methods I can find to remove multiple instances of the same element from an array. Using filter creates a new array and is slower so I would avoid that.


You have a built in function called filter that filters an array based on a predicate (a condition).

It doesn't alter the original array but returns a new filtered one.

var array=["hello","hello","world",1,"world"];
var filtered = array.filter(function(element) {
    return element !== "hello";
}); // filtered contains no occurrences of hello

You can extract it to a function:

function without(array, what){
    return array.filter(function(element){ 
        return element !== what;
    });
}

However, the original filter seems expressive enough.

Here is a link to its documentation

Your original function has a few issues:

  • It iterates the array using a for... in loop which has no guarantee on the iteration order. Also, don't use it to iterate through arrays - prefer a normal for... loop or a .forEach
  • You're iterating an array with an off-by-one error so you're skipping on the next item since you're both removing the element and progressing the array.

I thinks this code much simpler to understand and no need to pass manually each element that what we want to remove

ES6 syntax makes our life so simpler, try it out

const removeOccurences = (array)=>{
const newArray= array.filter((e, i ,ar) => !(array.filter((e, i ,ar)=> i !== ar.indexOf(e)).includes(e)))
console.log(newArray) // output [1]
}
removeOccurences(["hello","hello","world",1,"world"])