ChatGPT解决这个技术问题 Extra ChatGPT

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

This question already has answers here: How can I remove a specific item from an array? (136 answers) Closed 2 years ago.

Is there a method to remove an item from a JavaScript array?

Given an array:

var ary = ['three', 'seven', 'eleven'];

I would like to do something like:

removeItem('seven', ary);

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

PLEASE USE --> Array.filter()
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'

M
Maciej Krawczyk

You can use the indexOf method like this:

var index = array.indexOf(item);
if (index !== -1) {
  array.splice(index, 1);
}

Note: You'll need to shim it for IE8 and below

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


And loop on it while the index isn't -1
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
If you use jquery, you can use $.inArray instead of indexOf, which is cross browser compatible.
Make sure index!==(-1) , i.e. item exists in array, or else you will splice out the last element in array.
T
TuralAsgar

A one-liner will do it,

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).


Wondering this wonderful one-liner does not get more love. +1 No loops. One can add as many as values he want to remove by using && for values.
@bamboon The filter function checks whether an element meets the criteria. The function is executed with each element one by one and upon returning true, the resulting array will retain the element. It is omitted on false.
This is really straightforward, with the caveat mentioned by @SLaks that it creates a copy of the array, and doesn't affect references to the variable.
Note that this should be used as array = array.filter(), not just array.filter().
Updated answer with @JeffreyRoosendaal contribution (filter() does not mutate the array on which it is called. from developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ).
C
Community

This can be a global function or a method of a custom object, if you aren't allowed to add to native prototypes. It removes all of the items from the array that match any of the arguments.

Array.prototype.remove = function() {
    var what, a = arguments, L = a.length, ax;
    while (L && this.length) {
        what = a[--L];
        while ((ax = this.indexOf(what)) !== -1) {
            this.splice(ax, 1);
        }
    }
    return this;
};

var ary = ['three', 'seven', 'eleven'];

ary.remove('seven');

/*  returned value: (Array)
three,eleven
*/

To make it a global-

function removeA(arr) {
    var what, a = arguments, L = a.length, ax;
    while (L > 1 && arr.length) {
        what = a[--L];
        while ((ax= arr.indexOf(what)) !== -1) {
            arr.splice(ax, 1);
        }
    }
    return arr;
}
var ary = ['three', 'seven', 'eleven'];
removeA(ary, 'seven');


/*  returned value: (Array)
three,eleven
*/

And to take care of IE8 and below-

if(!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(what, i) {
        i = i || 0;
        var L = this.length;
        while (i < L) {
            if(this[i] === what) return i;
            ++i;
        }
        return -1;
    };
}

@xorinzor No, the .prototype property is cross-browser.
Never change Array prototype. Funny things starts to happen.
@madeinstefano, one or two examples of the funny (bad) things that would happen?
why do people show examples adding to the array prototype? stack overflow is for learning good practices
@YonnTrimoreau and what? define a non-enumerable property Object.defineProperty(Array.prototype, "remove", {enumerable : false});
J
Julius Musseau

You can use underscore.js. It really makes things simple.

For example, with this:

var result = _.without(['three','seven','eleven'], 'seven');

And result will be ['three','eleven'].

In your case the code that you will have to write is:

ary = _.without(ary, 'seven')

It reduces the code that you write.


I never said don't use the library in other places. If the code looks cleaner then i don't mind including a library. Why do people use jquery , why not use raw javascript then?
@vatsal - because library developers can concentrate on making the functions behind their library functions fast, concise and cross browser, while I get to concentrate on my application and its purpose. It saves me thinking time so that I have extra time to make the application better and not worrying about the small functions that makeup my application. Someone already invented the wheel, why would someone remake it every time they build a car?
Hi Kelvin i totally agree with you. A person had a put a comment and he removed it later, he was saying that using libraries like underscore is not cool and we should not accept such answers. I was trying to answer it.
Do note this will not modify the array in place; A new array will be returned instead.
A
AmerllicA

You can do it with these two ways:

const arr = ['1', '2', '3', '4'] // we wanna delete number "3"

The first way: arr.indexOf('3') !== -1 && arr.splice(arr.indexOf('3'), 1) The second way (ES6) specially without mutate: const newArr = arr.filter(e => e !== '3')


g
gadlol

Check out this way:

for(var i in array){
    if(array[i]=='seven'){
        array.splice(i,1);
        break;
    }
}

and in a function:

function removeItem(array, item){
    for(var i in array){
        if(array[i]==item){
            array.splice(i,1);
            break;
        }
    }
}

removeItem(array, 'seven');

Keep in mind if you modify this code to not "break" and continue looping to remove multiple items, you'll need to recalculate the i variable right after the splice, like so: i--. That's because you just shrunk the array and you'll end up skipping an element otherwise.
To add to my above comment, the code would then be: for (var i = 0; i < array.length; i++) {/*etc...*/ array.splice(i,1); i--;
Hi... Question, how to remove multiple array? I tried removeItem(array, 'seven, eight') but it's not working.
J
Jackkobec

The simplest solution is:

array - array for remove some element valueForRemove; valueForRemove - element for remove;

array.filter(arrayItem => !array.includes(valueForRemove));

More simple:

array.filter(arrayItem => arrayItem !== valueForRemove);

No pretty, but works:

array.filter(arrayItem => array.indexOf(arrayItem) != array.indexOf(valueForRemove))

No pretty, but works:

while(array.indexOf(valueForRemove) !== -1) {
  array.splice(array.indexOf(valueForRemove), 1)
}

P.S. The filter() method creates a new array with all elements that pass the test implemented by the provided function. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter


Thats not even close to the correct answer? You should edit this for the working example. It's confusing now.
while i like this approach because it uses immutable data structures, this isn't a catch-all solution because sometimes the developer does want to mutate the array in place
The filter() method creates a new array with all elements that pass the test implemented by the provided function. See developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
This works as the right side of an assignment: newArray = array.filter... Then: array = newArray and the item is gone from array.
Documentation about filter() is absolutely understandable.
C
Chiaro

You can create your own method, passing throught the array and the value you want removed:

function removeItem(arr, item){
 return arr.filter(f => f !== item)
}

Then you can call this with:

ary = removeItem(ary, 'seven');

M
Matee Gojra

Method 1

var ary = ['three', 'seven', 'eleven'];
var index = ary.indexOf('seven'); // get index if value found otherwise -1

if (index > -1) { //if found
  ary.splice(index, 1);
}

Method 2

One liner Solution

var ary = ['three', 'seven', 'eleven'];
filteredArr = ary.filter(function(v) { return v !== 'seven' })


// Or using ECMA6:
filteredArr = ary.filter(v => v !== 'seven')

Thank you for this code snippet, which might provide some limited, immediate help. A proper explanation would greatly improve its long-term value by showing why this is a good solution to the problem, and would make it more useful to future readers with other, similar questions. Please edit your answer to add some explanation, including the assumptions you've made.
worked best in my case as I wanted to delete from an array with the value (to delete) stored to a variable. Thanks!
C
CorayThan

Here's a version that uses jQuery's inArray function:

var index = $.inArray(item, array);
if (index != -1) {
    array.splice(index, 1);
}

Splice supports negative indices to take from the end, so if the item is not found, this code removes the last item from the array.
@dman2306 Huh, didn't see your comment until now, but that's a really good point. Fixed it for that issue.
K
Kld
var index = array.indexOf('item');

if(index!=-1){

   array.splice(index, 1);
}

C
Community

What you're after is filter

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

This will allow you to do the following:

var ary = ['three', 'seven', 'eleven'];
var aryWithoutSeven = ary.filter(function(value) { return value != 'seven' });
console.log(aryWithoutSeven); // returns ['three', 'eleven']

This was also noted in this thread somewhere else: https://stackoverflow.com/a/20827100/293492


That will not mutate the array.
No; that assigns the variable to point to a new object. If you have other references to the original array, they will not be affected.
O
Oliver Dixon

ES6 way.

const commentsWithoutDeletedArray = commentsArray.filter(comment => comment.Id !== commentId);

I think mapreduce functions in javascript are pretty fast, but splice would still be faster. so a better implementation might be const removeArrayItem = (arr, itemToRemove) => { return arr.includes(itemToRemove)? arr.splice(arr.indexOf(itemToRemove), 1): arr }
@robertotomás I prefer readability over slight performance gains.
Hey @OliverDixon can u please explain more comment.Id !== commentId now the commecnt i want delete is 5 now in filter 5 !== 5 it's false so how dose delete it :\?
@OliverDixon in case you need the performance, you can simply wrap that unreadable code into your own readable function.
g
greene

If you have unique values and ordering doesn't matter, use Set, it has delete():

var mySet = new Set(['three', 'seven', 'eleven']);
mySet.delete('seven'); // Returns true, successfully removed    
[...mySet];            // Returns ['three', 'eleven']

r
rbenvenuto

Really, i can't see why this can't be solved with

arr = arr.filter(value => value !== 'seven');

Or maybe you want to use vanilla JS

arr = arr.filter(function(value) { return value !== 'seven' });

Maybe because it doesn't remove the item from the array?
Yes, it doesn't, it creates a new array without the string 'seven'
It works for me thx. arr = arr.filter(value => value !== 'seven');
O
Olcay Ertaş

When you need to remove a value present multiple times in the array(e.g. [1,2,2,2, 4, 5,6]).

function removeFrmArr(array, element) {
  return array.filter(e => e !== element);
};
var exampleArray = [1,2,3,4,5];
removeFrmArr(exampleArray, 3);
// return value like this
//[1, 2, 4, 5]

You can use splice to remove a single element from the array but splice can't remove multiple similar elements from the array.

function singleArrayRemove(array, value){
  var index = array.indexOf(value);
  if (index > -1) array.splice(index, 1);
  return array;
}
var exampleArray = [1,2,3,4,5,5];
singleArrayRemove(exampleArray, 5);
// return value like this
//[1, 2, 3, 4, 5]

You should consider adding some explanation to your code.
Line 5 should be removeFrmArr(exampleArray, 3);, current code throws a ReferenceError.
S
Shakespeare

Seeing as there isn't a pretty one, here's a simple and reusable ES6 function.

const removeArrayItem = (arr, itemToRemove) => {
  return arr.filter(item => item !== itemToRemove)
}

Usage:

const items = ['orange', 'purple', 'orange', 'brown', 'red', 'orange']
removeArrayItem(items, 'orange')

removeArrayItem method doesn't remove item from the array. It creates new array without item.
Correct @WebBrother. From a 'consumer' point of view, the implementation is not really my concern - if I give it an array and an item, I get an array back with the item removed, so the name makes sense to me. Thoughts?
If you're going to use ES6, make sure you're using the correct comparison (avoid !== and instead use !Object.is(item, itemToRemove).
J
Jason

Removing all matching elements from the array (rather than just the first as seems to be the most common answer here):

while ($.inArray(item, array) > -1) {
    array.splice( $.inArray(item, array), 1 );
}

I used jQuery for the heavy lifting, but you get the idea if you want to go native.


So you run $.inArray twice if an item is found, why not store the index on the first run and re-use that? #effectiveprogramming #resourcesdonotgrowontrees. while( ( index = $.inArray(item,array) ) > -1 ) array.splice( index, 1 );
E
Eugene Lyzo

In all values unique, you can:

a = new Set([1,2,3,4,5]) // a = Set(5) {1, 2, 3, 4, 5}
a.delete(3) // a = Set(5) {1, 2, 4, 5} 
[...a] // [1, 2, 4, 5]

d
dcordz

a very clean solution working in all browsers and without any framework is to asign a new Array and simply return it without the item you want to delete:

/**
 * @param {Array} array the original array with all items
 * @param {any} item the time you want to remove
 * @returns {Array} a new Array without the item
 */
var removeItemFromArray = function(array, item){
  /* assign a empty array */
  var tmp = [];
  /* loop over all array items */
  for(var index in array){
    if(array[index] !== item){
      /* push to temporary array if not like item */
      tmp.push(array[index]);
    }
  }
  /* return the temporary array */
  return tmp;
}

+1 for a clean solution. Too many answers tend to suggest one 3rd party resource or another when sometimes we need a purer solution (and they are all great just not in all use cases).
a
aaaaaaaaaaaa

indexOf is an option, but it's implementation is basically searching the entire array for the value, so execution time grows with array size. (so it is in every browser I guess, I only checked Firefox).

I haven't got an IE6 around to check, but I'd call it a safe bet that you can check at least a million array items per second this way on almost any client machine. If [array size]*[searches per second] may grow bigger than a million you should consider a different implementation.

Basically you can use an object to make an index for your array, like so:

var index={'three':0, 'seven':1, 'eleven':2};

Any sane JavaScript environment will create a searchable index for such objects so that you can quickly translate a key into a value, no matter how many properties the object has.

This is just the basic method, depending on your need you may combine several objects and/or arrays to make the same data quickly searchable for different properties. If you specify your exact needs I can suggest a more specific data structure.


Mind that this is NOT clugy as an associative array is actually an object: var arr = []; arr['zero'] = 1, arr['one'] = 2; is equivalent to: {zero: 1, one: 2}
P
Penny Liu

You can achieve this using Lodash _.remove function.

var array = ['three', 'seven', 'eleven']; var evens = _.remove(array, function(e) { return e !== 'seven'; }); console.log(evens);


s
sakovias

You can use without or pull from Lodash:

const _ = require('lodash');
_.without([1, 2, 3, 2], 2); // -> [1, 3]

c
chaoticflow

The trick is to go through the array from end to beginning, so you don't mess up the indices while removing elements.

var deleteMe = function( arr, me ){
   var i = arr.length;
   while( i-- ) if(arr[i] === me ) arr.splice(i,1);
}

var arr = ["orange","red","black", "orange", "white" , "orange" ];

deleteMe( arr , "orange");

arr is now ["red", "black", "white"]


R
Randhir Rawatlal

Non-destructive removal:

function removeArrayValue(array, value)
{
    var thisArray = array.slice(0); // copy the array so method is non-destructive

    var idx = thisArray.indexOf(value); // initialise idx

    while(idx != -1)
    {
        thisArray.splice(idx, 1); // chop out element at idx

        idx = thisArray.indexOf(value); // look for next ocurrence of 'value'
    }

    return thisArray;
}

A
Alexander Abashkin
var remove = function(array, value) {
    var index = null;

    while ((index = array.indexOf(value)) !== -1)
        array.splice(index, 1);

    return array;
};

I like this approach... I used this approach on a LeetCode question.
m
mmohab

Please do not use the variant with delete - it makes a hole in the array as it does not re-index the elements after the deleted item.

> Array.prototype.remove=function(v){
...     delete this[this.indexOf(v)]
... };
[Function]
> var myarray=["3","24","55","2"];
undefined
> myarray.remove("55");
undefined
> myarray
[ '3', '24', , '2' ]

m
maudulus

I used the most voted option and created a function that would clean one array of words using another array of unwanted words:

function cleanArrayOfSpecificTerms(array,unwantedTermsArray) {
  $.each(unwantedTermsArray, function( index, value ) {
    var index = array.indexOf(value);
    if (index > -1) {
      array.splice(index, 1);        
    }
  });
  return array;
}

To use, do the following:

var notInclude = ['Not','No','First','Last','Prior','Next', 'dogs','cats'];
var splitTerms = ["call", "log", "dogs", "cats", "topic", "change", "pricing"];

cleanArrayOfSpecificTerms(splitTerms,notInclude)

A
Asif vora
let arr = [5, 15, 25, 30, 35];
console.log(arr); //result [5, 15, 25, 30, 35]
let index = arr.indexOf(30);

if (index > -1) {
   arr.splice(index, 1);
}
console.log(arr); //result [5, 15, 25, 35]

S
Srikrushna

In a global function we can't pass a custom value directly but there are many way as below

 var ary = ['three', 'seven', 'eleven'];
 var index = ary.indexOf(item);//item: the value which you want to remove

 //Method 1
 ary.splice(index,1);

 //Method 2
 delete ary[index]; //in this method the deleted element will be undefined

delete shouldn't be used because it removes the value only but leave the space.