19

I am trying to make a removeAll() function, which will remove all elements of an array with that particular value (not index).

The tricky part comes when we make any change to the loop, the indexes tend to move around (making it very hard to make it work like we want) and, restarting the loop every time we make changes is very inefficient on big arrays.

So far, I wrote my own arr.indexOf function (for older IE support), it looks like this:

function arrFind(val, arr) {
    for (var i = 0, len = arr.length, rtn = -1; i < len; i++) {
        if (arr[i] === val) {
            return i;
        }
    }
    return -1;
}

It is easy to remove elements like this:

var myarray = [0, 1, 2, 3, 4];
var tofind = 2;

var stored_index = arrFind(tofind, myarray);
if (stored_index != -1) {
    myarray.splice(stored_index, 1);
}

alert(myarray.join(",")); //0,1,3,4

However, as I pointed out earlier, when doing this while looping, we get in trouble.

Any ideas on how to properly remove array items while looping through it?

1
  • found this related question (but is not a dup because my question is about a problem when removing multiple items inside a loop) Commented May 29, 2012 at 21:24

4 Answers 4

44

Loop in reverse order or build a new array with the items that are not to be removed.

Sign up to request clarification or add additional context in comments.

4 Comments

building a new array only with the items that are != to the one I want to remove is a good idea!, I will do this.
You are a goddamn hero!!
Here is a JSPerf comparing this with answer of a similar question : jsperf.com/splice-vs-pack/11 For small arrays this is just efficient. For very large arrays, marking for removal and then packing the array is much more efficient.
BTW, efficiency depends on the number of elements to delete. If not too many to delete, then splicing in reverse order is better than building a new array or setting to undefined and then packing the array.
24

Every new browser has an Array filter method:

var myarray=[0,1,2,3,4];
var removal=2;
var newarray=myarray.filter(function(itm){return itm!==removal});

2 Comments

what will be the solution if removal will be equal with [0,2,4] ?
@Asking you would additionally iterate over the removal inside the filter callback checking if either of the values match the item and returning the result of this comparison
5

Try this one. You just have to check the indices of the numbers you would like to remove. I have added additional elements in your array.

var myarray = [0, 1, 2, 3, 2, 2, 2, 5, 6];
var indicesToRemove = new Array();

for(i=0;i<myarray.length;i++){
    if(myarray[i]===2){ //let's say u wud like to remove all 2 
        indicesToRemove.push(i); //getting the indices and pushing it in a new array
    }
}

for (var j = indicesToRemove.length -1; j >= 0; j--){
    myarray.splice(indicesToRemove[j],1);
}

alert(JSON.stringify(myarray)); //myarray will be [0,1,3,5,6]

1 Comment

This answer is better than the accepted one, because it has code and actually preserves the order of deletion.
1

I wrote this little function where arr is the original array and d1, d2 the values you want removed. I wonder how it could be generalized to an arbitrary number of values to be removed. Well, I'm just a beginner.

function destroyer(arr, d1, d2) {
    var lean =[];
    for (var i = 0; i<arr.length; i++) {
        if (arr[i] != d1 && arr[i] != d2) {
            lean.push(arr[i]);
        }
    }
  return lean;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.