Javascript array remove element by value

javascript — remove array element on condition

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 = [ , , ]; 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 = [ , , ]; ar.removeIf( function(item, idx) < return idx == 2; >); 

11 Answers 11

The code would look like this:

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

Keep in mind that Array.filter method creates a new array. If you reference your array in another variable, the reference will be broken afterwards: ar1 = [1, 2, 3, 4]; ar2 = ar1; ar1 = ar1.filter(item => !(item > 3)); console.log(ar1); console.log(ar2);

Читайте также:  Java if false example

This doesn’t remove items from the array. This produces a new array and assigns to the ar variable. If any other variables have referenced the initial array in ar , they are not updated/affected. I would not consider this answer

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.

Thanks, works great. I like how this takes into consideration the index changes through splicing during iteration.

That’s a little messy. Try jsfiddle.net/n8JEy/4 — and you didn’t pass i to the callback as the second param

@Ian I tend to prefer readability, but your solution is certainly more efficient. I also added the index as the second parameter (simply ignored it originally as it was not used, and I assumed that he didn’t need it).

@dk123 As a newcomer to JavaScript, you are free to control the parameters of such callbacks as you see fit, and you can add whatever you want to them so long as the information is available (e.g., you could add the current array’s length using this.length as a third parameter, if you had some inclination).

Mutating prototype of a predefined class is risky. Should be done only in polyfill-ish fashion, i. e. to add members which are already declared in specs but not implemented by browsers yet. Thanks for the solution, I’m using it as a local function.

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

As a head’s up that is not supported in IE8 or below. You should also either negate the original expression, or it should be

Doesn’t Array.filter() return a new array with the filtered elements? Is there something that just removes the elements from the array?

Making a new array with Array.filter will likely be faster than manually splicing out of the given array.

@Blender That’s very interesting. I swear I just looked into something recently comparing the two and it was the opposite. Stupid comment of mine deleted. Thanks for providing that for proof 🙂

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] 

Make it a one-liner with arrow function:

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

var ar = [ , , ]; var newArray = []; for (var i = 0, len = ar.length; i; >; console.log(newArray); 

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 = [ , , , ]; ar.removeById = ar.splice(ar.findIndex(el => el.id === id), 1); ar.removeById(ID_TO_REMOVE); 

splice() + findIndex() isn’t faster than just filter() ‘ing out the removed values. Or is it in some cases?

whattt a failure here snips off the last array item at index -1. «if you know for sure it exists» is a bad premise.

My solution for an array of numbers would be:

@Marcel, it is a good answer if you don’t mind losing the reference to the original array, as per this comment: stackoverflow.com/questions/15995963/… The question has no reassignment, implying a solution that manipulates the original array is what is requested.

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> return res; > ar = [ 1, 2, 3, 4 ]; var result = ar.removeIf(expCallBack); console.log(result); function expCallBack(item) < return item >3; > 

Could you perhaps modify(or add another method) your code a bit to actually remove elements instead of returning a new array? Thanks for the reply.

whoever downvoted this so wrong. this is the best perfoming answer out of all of them. check the test by @Blender jsperf.com/splice-vs-filter. it’s at least 2x faster and as much as 15x faster in the latest versions of Firefox

For the in-place remove, my solution is

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

Incorrect way

First of all, any answer that suggests to use filter does not actually remove the item. Here is a quick test:

var numbers = [1, 2, 2, 3]; numbers.filter(x => x === 2); console.log(numbers.length); 

In the above, the numbers array will stay intact (nothing will be removed). The filter method returns a new array with all the elements that satisfy the condition x === 2 but the original array is left intact.

var numbers = [1, 2, 2, 3]; numbers = numbers.filter(x => x === 2); console.log(numbers.length); 

But that is simply assigning a new array to numbers .

Correct way to remove items from array

One of the correct ways, there are more than 1, is to do it as following. Please keep in mind, the example here intentionally has duplicated items so the removal of duplicates can be taken into consideration.

var numbers = [1, 2, 2, 3]; // Find all items you wish to remove // If array has objects, then change condition to x.someProperty === someValue var numbersToRemove = numbers.filter(x => x === 2); // Now remove them numbersToRemove.forEach(x => numbers.splice(numbers.findIndex(n => n === x), 1)); // Now check (this is obviously just to test) console.log(numbers.length); console.log(numbers); 

Now you will notice length returns 2 indicating only numbers 1 and 3 are remaining in the array.

Источник

The best way to remove array element by value

This reminds me of .filter(), present in mootools and jquery. Mootools also has, for instance, .erase(), which does just as you ask. There is no reason to reinvent the wheel.

10 Answers 10

var arr = ["orange","red","black","white"]; var index = arr.indexOf("red"); if (index >= 0)

This code will remove 1 occurency of «red» in your Array.

Also, you would have to augment your array to support .indexOf() which isn’t supported in some older versions of IE.

@IvanMalyshev agreed, this is extremely dangerous. Array.prototype.splice(index, howMany) allows negative index, so you need to check that indexOf does not return -1 (not found) before calling splice.

Really, how can this be the approved answer when i’ts demonstrably wrong, as per the comments by @IvanMalyshev and @Dakota? Downvoted, would upvote with appropriate correction.

Back when I was new to coding I could hardly tell what splice was doing, and even today it feels less readable.

But readability counts.

I would rather use the filter method like so:

arr = ["orange","red","black","white","red"] arr = arr.filter(val => val !== "red"); console.log(arr) // ["orange","black","white"] 

Note how all occurrences of «red» are removed from the array.

From there, you can easily work with more complex data such as array of objects.

arr = arr.filter(obj => obj.prop !== "red"); 

Источник

How to remove item from array by value? [duplicate]

I’ve looked into splice() but that only removes by the position number, whereas I need something to remove an item by its value.

I wrote various solutions for this (remove one or multiple values) and this is my ultimate solution (I benchmarked and it is faster than lodash). Have a go: gist.github.com/ardeshireshghi/0d97db4ae09bc2f90609c536fc63c648

I think most clean way to remove items from array is to use ary.filter() method of array. ary.filter(val => val !== ‘seven’ ). This will return new array with all elements expect ‘seven’

37 Answers 37

You can use the indexOf method like this:

var index = array.indexOf(item); if (index !== -1)
var array = [1,2,3,4] var item = 3 var index = array.indexOf(item); array.splice(index, 1); console.log(array)

It would be best to do a check to only splice if different than -1 , there are like millions of options, choose wisely jsperf.com/not-vs-gt-vs-ge/4

Make sure index!==(-1) , i.e. item exists in array, or else you will splice out the last element in array.

var arr = ['three', 'seven', 'eleven']; // Remove item 'seven' from array var filteredArray = arr.filter(function(e) < return e !== 'seven' >) //=> ["three", "eleven"] // In ECMA6 (arrow function syntax): var filteredArray = arr.filter(e => e !== 'seven') 

This makes use of the filter function in JS. It’s supported in IE9 and up.

What it does (from the doc link)

filter() calls a provided callback function once for each element in an array, and constructs a new array of all the values for which callback returns a value that coerces to true. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values. Array elements which do not pass the callback test are simply skipped, and are not included in the new array.

So basically, this is the same as all the other for (var key in ary) < . >solutions, except that the for in construct is supported as of IE6.

Basically, filter is a convenience method that looks a lot nicer (and is chainable) as opposed to the for in construct (AFAIK).

Источник

Оцените статью