18

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?

ajax333221
  • 10,585
  • 14
  • 56
  • 89
  • [found this related question](http://stackoverflow.com/q/3954438/908879) (but is _not_ a dup because my question is about _a problem_ when removing _multiple_ items _inside a loop_) – ajax333221 May 29 '12 at 21:24

4 Answers4

44

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

epascarello
  • 185,306
  • 18
  • 175
  • 214
  • 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. – ajax333221 Feb 15 '12 at 03:34
  • You are a goddamn hero!! – svarog May 10 '15 at 13:16
  • Here is a JSPerf comparing this with answer of a [similar question](http://stackoverflow.com/a/28409817/768685) : http://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. – Ali Ok Mar 01 '16 at 23:03
  • 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. – Ali Ok Mar 01 '16 at 23:14
23

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});
kennebec
  • 94,076
  • 30
  • 99
  • 125
4

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
    This answer is better than the accepted one, because it has code and actually preserves the order of deletion. – Nice Books Mar 15 '16 at 10:13
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;