标签云

微信群

扫码加入我们

WeChat QR Code

I have an array of integers, and I'm using the .push() method to add elements to it.

Is there a simple way to remove a specific element from an array? The equivalent of something like array.remove(int);.

I have to use core JavaScript - no frameworks are allowed.


If you need to support <IE9 (sigh) then check this SO question regarding indexOf in IE.

2018年07月18日49分14秒

(lodash) array = ['a', 'b', 'c']; _.pull(array, 'a') // array => ['b', 'c']; See also stackoverflow.com/questions/5767325/…

2018年07月17日49分14秒

filter method can do what you want.

2018年07月18日49分14秒

You can use delete but it will not rearange the index instead it will set this slot to 'undefined × 1'. For example: var list = [1,2,3,4,5,6] -> delete list[1] -> [1, undefined × 1, 3, 4, 5, 6].

2018年07月17日49分14秒

Here a performance benchmark of the two major possibilities: jsben.ch/#/b4Ume

2018年07月17日49分14秒

Peter, yes you might be right. This article explains more and has a workaround for incompatible browsers: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…

2018年07月17日49分14秒

Dangerous! If you are working with dynamic values (add and remove dynamic values from array) and value is not exist in array (the index become -1) the code above will remove the last element of the array.

2018年07月17日49分14秒

AlexandreWiechersVaz Of course it preserves order, if it didn't then it would be absolutely worthless

2018年07月18日49分14秒

You can overcome the IE browser support problem by including the code given here

2018年07月17日49分14秒

AdrianP. array.indexOf(testValue) on empty array will be -1, and if you're testing for that then no splice. Maybe the answer has changed since.

2018年07月17日49分14秒

delete is not the correct way to remove an element from an array!

2018年07月17日49分14秒

FelixKling It depends, it works if you want to make it so that array.hasOwnProperty(i) returns false and have the element at that position return undefined. But I'll admit that that's not a very common thing to want to do.

2018年07月17日49分14秒

delete will not update the length of the array neither really erases the element, only replaces it with the special value undefined.

2018年07月17日49分14秒

diosney I don't know what you mean when you say it doesn't really erase the element. Further, it does more than simply replacing the value at that index with undefined: it removes both the index and the value from the array, i.e. after delete array[0], "0" in array will return false.

2018年07月17日49分14秒

delete is a good mechanism if you are dealing with named properties var array=[];array['red']=1;array['green']=2;array['blue']=3;delete array['green'];

2018年07月17日49分14秒

but, sometimes we want to remove element from original array(non immutable), for example array used in Angular 2 *ngFor directive

2018年07月17日49分14秒

Better than the accepted solution because it does not assume only one occurrence of a match and immutability is preferable

2018年07月18日49分14秒

Using filter is so much nicer than using splice. Too simple.

2018年07月17日49分14秒

filter must be much slower for a big array though?

2018年07月18日49分14秒

What's the point of immutability mentioned if you used assignment of the same variable in your examples? :)

2018年07月18日49分14秒

It's worth noting that var value will not store the removed value but an array containing the removed value.

2018年07月17日49分14秒

delete is not the correct way to remove an element from an array!!

2018年07月17日49分14秒

If you want to "empty a slot", use array[index] = undefined;. Using delete will destroy optimisation.

2018年07月18日49分14秒

Jakub very good comment because to understand that I lost much time and thought my application code is somehow broken...

2018年07月18日49分14秒

sroes it should not be because the loop starts at i = arr.length -1 or i-- making it same as the max index. arr.length is just an initial value for i. i-- will always be truthy (and reducing by 1 at each loop op) until it equals 0 (a falsy value) and the loop will then stop.

2018年07月17日49分14秒

Second function is rather inefficient. On every iteration "indexOf" will start search from beginning of array.

2018年07月17日49分14秒

AmberdeBlack, on a collection with more than 1 occurrence of item, it's much better to call the filter method instead arr.filter(function (el) { return el !== item }), avoiding the need to mutate the array multiple times. This consumes slightly more memory, but operates much more efficiently, since there's less work that needs to be done.

2018年07月17日49分14秒

AlJey, it's available only from IE9+. There is still a chance that it wouldn't work.

2018年07月17日49分14秒

This answer worked for me because I needed several items removed but not in any particular order. The backwards progression of the for loop here handles removing items from the array perfectly.

2018年07月17日49分14秒

I'm not a big fan of this approach. If you end up using different libraries or frameworks, they can end up conflicting with each other.

1970年01月01日00分03秒

This worked as well, I chose to go with the indexOf function in the end though. Thanks for the help!

2018年07月17日49分14秒

Bad idea, see this post: stackoverflow.com/questions/948358/array-prototype-problem

2018年07月17日49分14秒

If you're doing a for in on an array, you already have a problem.

2018年07月18日49分14秒

Looks like the 'move' method presented here should work in all browsers, and also avoids creating an extra array; most other solutions here have one or both of these problems. I think this one deserves a lot more votes, even if it doesn't look as "pretty".

2018年07月17日49分14秒

I don't know that you need the -1 check (i > -1). Also, I think these functions act more like filter than remove. If you pass row.id === 5, it will result in an array with only id 5, so it is doing the opposite of remove. It would look nice in ES2015: var result = ArrayHelper.remove(myArray, row => row.id === 5);

2018年07月17日49分14秒

WhatWouldBeCool this function modify the original array, and return the removed item instead of copying the result to a new array

2018年07月18日49分14秒

Just learned by the hard way why it is a good idea to use Object.prototype.hasOwnProperty always ¬¬

2018年07月18日49分14秒

Nice solution but I see one problem and that is it creates new array and doesn't do anything to original array.

2018年07月17日49分14秒

Mak you are correct. This indeed creates another array. But if you do not want to do this you can overwrite old one with a new one.

2018年07月17日49分14秒

Also note, Array.prototype.filter is ECMAScript 5.1 (No IE8)

2018年07月17日49分14秒

Do you have a source on that this is faster?

2018年07月18日49分14秒

Nice solution. But as you point out, but important to make bald, it does not produce the same result as slice and indexOf since it will remove all occurrences of 1

2018年07月17日49分14秒

This answer is nice because it creates a copy of the original array, instead of modifying the original directly.

2018年07月17日49分14秒

RolandIllig Except the use of a for in-loop and the fact that the script could stopped earlier, by returning the result from the loop directly. The upvotes are reasonable ;)

2018年07月17日49分14秒

This is an excellent approach for small arrays. It works in every browser, uses minimal and intuitive code, and without any extra complex frameworks, shims, or polyfills.

2018年07月17日49分14秒

I should also reiterate yckart's comment that for( i = 0; i < arr.length; i++ ) would be a better approach since it preserves the exact indices versus whatever order the browser decides to store the items (with for in). Doing so also lets you get the array index of a value if you need it.

2018年07月17日49分14秒

That's not core JS as the OP requested, is it?

2018年07月18日49分14秒

some-non-descript-user You are right. But a lot of users like me come here looking for a general answer not just for the OP only.

2018年07月17日49分14秒

ChunYang You are absolutely right. I am already using lodash, why not just use it if it saves time.

2018年07月17日49分14秒

There is a small typo. Please correct. this.splice(num.indexOf(x), 1); => this.splice(this.indexOf(x), 1);

2018年07月17日49分14秒

Thanks for that, just fix it

2018年07月17日49分14秒

Please don't augment built-ins (attach functions to Array.prototype) in JavaScript. This is widely regarded as bad practice.

2018年07月17日49分14秒

I agree that's not the best thing to do in the world, but in this case how you could pass down it to the function?

2018年07月17日49分14秒

You should check the index. If index = -1, splice(-1,1) will remove the last element

2018年07月17日49分14秒

This is how I like to do it. Using an arrow function it can be a one-liner. I'm curious about performance. Also worth nothing that this replaces the array. Any code with a reference to the old array will not notice the change.

2018年07月17日49分14秒

Note that .filter returns a new array, which is not exactly the same as removing the element from the same array. The benefit of this approach is that you can chain array methods together. eg: [1,2,3].filter(n => n%2).map(n => n*n) === [ 1, 9 ]

2018年07月17日49分14秒

Great, if I have 600k elements in array and want to remove first 50k, can you imagine that slowness? This is not solution, there's need for function which just remove elements and returns nothing.

2018年07月17日49分14秒

Seraph For that, you'd probably want to use splice or slice.

2018年07月17日49分14秒

bjfletcher Thats even better, in process of removal, just allocate 50K elements and throw them somewhere. (with slice 550K elements, but without throwing them from the window).

2018年07月17日49分14秒

I'd prefer bjfletcher's answer, which could be as short as items= items.filter(x=>x!=3). Besides, the OP didn't state any requirement for large data set.

1970年01月01日00分03秒

Just a note, 1 caveat with this method is the potential for stack overflows. Unless you're working with massive arrays, you shouldn't have an issue.

2018年07月18日49分14秒

Are redundant constructions the norm around web developers? I have someone at work spraying stuff like this everywhere. Why not just return value != elem?!

2018年07月17日49分14秒

Buffalo, thanks for the suggestion.

2018年07月17日49分14秒