javascript - remove array element on condition

Javascript

Javascript Problem Overview


I was wondering how I'd go about implementing a method in javascript that removes all elements of an array that clear a certain condition. (Preferably without using jQuery)

Ex.

ar = [ 1, 2, 3, 4 ];
ar.removeIf( function(item, idx) {
    return item > 3;
});

The above would go through each item in the array and remove all those that return true for the condition (in the example, item > 3).

I'm just starting out in javascript and was wondering if anyone knew of a short efficient way to get this done.

--update--

It would also be great if the condition could work on object properties as well.

Ex.

ar = [ {num:1, str:"a"}, {num:2, str:"b"}, {num:3, str:"c"} ];
ar.removeIf( function(item, idx) {
    return item.str == "c";
});

Where the item would be removed if item.str == "c"

--update2--

It would be nice if index conditions could work as well.

Ex.

ar = [ {num:1, str:"a"}, {num:2, str:"b"}, {num:3, str:"c"} ];
ar.removeIf( function(item, idx) {
    return idx == 2;
});

Javascript Solutions


Solution 1 - Javascript

You can use Array filter method.

The code would look like this:

ar = [1, 2, 3, 4];
ar = ar.filter(item => !(item > 3));
console.log(ar) // [1, 2, 3]

Solution 2 - Javascript

You could add your own method to Array that does something similar, if filter does not work for you.

Array.prototype.removeIf = function(callback) {
    var i = 0;
    while (i < this.length) {
        if (callback(this[i], i)) {
            this.splice(i, 1);
        }
        else {
            ++i;
        }
    }
};

To me, that's one of the coolest features of JavaScript. Ian pointed out a more efficient way to do the same thing. Considering that it's JavaScript, every bit helps:

Array.prototype.removeIf = function(callback) {
    var i = this.length;
    while (i--) {
        if (callback(this[i], i)) {
            this.splice(i, 1);
        }
    }
};

This avoids the need to even worry about the updating length or catching the next item, as you work your way left rather than right.

Solution 3 - Javascript

You can use Array.filter(), which does the opposite:

ar.filter(function(item, idx) {
    return item <= 3;
});

Solution 4 - Javascript

You can use lodash.remove

var array = [1, 2, 3, 4];
var evens = _.remove(array, function(n) {
  return n % 2 == 0;
});
 
console.log(array);
// => [1, 3]
 
console.log(evens);
// => [2, 4]

Solution 5 - Javascript

Make it a one-liner with arrow function:

ar = ar.filter(i => i > 3);

Solution 6 - Javascript

I love these kinds of questions and just a different version from me too... :)

Array.prototype.removeIf = function(expression) {
   var res = [];
    for(var idx=0; idx<this.length; idx++)
    {
      var currentItem = this[idx];
        if(!expression(currentItem))
        {
            res.push(currentItem);
        }
    }
    return res;
}

ar = [ 1, 2, 3, 4 ];
var result = ar.removeIf(expCallBack);


console.log(result);
function expCallBack(item)
{
    return item > 3;
}

Solution 7 - Javascript

simply write the following example if condition could work on object properties as well

var ar = [ {num:1, str:"a"}, {num:2, str:"b"}, {num:3, str:"c"} ];
var newArray = [];
for (var i = 0, len = ar.length; i<len; i++) {
        if (ar[i].str == "b") 
        {newArray.push(ar[i]);};
 };
console.log(newArray);

See the example Live Example

Solution 8 - Javascript

if you need to remove exactly one item, and you know for sure that the item exists, you can use this one-liner:

ar.splice(ar.findIndex(el => el.id === ID_TO_REMOVE), 1);

// or with custom method:
let ar = [ {id:1, str:"a"}, {id:2, str:"b"}, {id:3, str:"c"}, {id:4,str:"d"} ];
ar.removeById = id => ar.splice(ar.findIndex(el => el.id === id), 1);
ar.removeById(ID_TO_REMOVE);

http://jsfiddle.net/oriadam/72kgprw5/

ES6 only

Solution 9 - Javascript

My solution for an array of numbers would be:

ar.filter(item => item < 4);

Solution 10 - Javascript

For the in-place remove, my solution is

ar.filter(item => !(item > 3))
  .forEach(obsoleteItem => ar.splice(ar.indexOf(obsoleteItem), 1));

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questiondk123View Question on Stackoverflow
Solution 1 - JavascriptKlaster_1View Answer on Stackoverflow
Solution 2 - JavascriptpickypgView Answer on Stackoverflow
Solution 3 - JavascriptBlenderView Answer on Stackoverflow
Solution 4 - JavascriptSatoshi SuzukiView Answer on Stackoverflow
Solution 5 - Javascriptmichal.jakubeczyView Answer on Stackoverflow
Solution 6 - JavascriptPSLView Answer on Stackoverflow
Solution 7 - JavascriptvamsikrishnamannemView Answer on Stackoverflow
Solution 8 - JavascriptoriadamView Answer on Stackoverflow
Solution 9 - JavascriptFrank WaalkensView Answer on Stackoverflow
Solution 10 - JavascriptSimonView Answer on Stackoverflow