Javascript 如何从数组中删除特定项目?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5767325/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I remove a specific item from an array?
提问by Walker
I have an array of numbers and I'm using the .push()
method to add elements to it.
我有一个数字数组,我正在使用该.push()
方法向其中添加元素。
Is there a simple way to remove a specific element from an array?
有没有一种简单的方法可以从数组中删除特定元素?
I'm looking for the equivalent of something like:
我正在寻找类似的东西:
array.remove(number);
I have to use coreJavaScript. Frameworks are not allowed.
我必须使用核心JavaScript。不允许使用框架。
回答by Tom Wadley
Find the index
of the array element you want to remove using indexOf
, and then remove that index with splice
.
使用 查找index
要删除的数组元素的indexOf
,然后使用 删除该索引splice
。
The splice() method changes the contents of an array by removing existing elements and/or adding new elements.
splice() 方法通过删除现有元素和/或添加新元素来更改数组的内容。
const array = [2, 5, 9];
console.log(array);
const index = array.indexOf(5);
if (index > -1) {
array.splice(index, 1);
}
// array = [2, 9]
console.log(array);
The second parameter of splice
is the number of elements to remove. Note that splice
modifies the array in place and returns a new array containing the elements that have been removed.
的第二个参数splice
是要删除的元素数。请注意,splice
在原地修改数组并返回一个包含已删除元素的新数组。
For the reason of completeness, here are functions. First function removes only single occurrence (i.e. removing first match of 5
from [2,5,9,1,5,8,5]
), while second function removes all occurrences:
为了完整起见,这里是函数。第一个函数仅删除单个出现(即删除5
from 的第一个匹配项[2,5,9,1,5,8,5]
),而第二个函数删除所有出现:
function removeItemOnce(arr, value) {
var index = arr.indexOf(value);
if (index > -1) {
arr.splice(index, 1);
}
return arr;
}
function removeItemAll(arr, value) {
var i = 0;
while (i < arr.length) {
if(arr[i] === value) {
arr.splice(i, 1);
} else {
++i;
}
}
return arr;
}
回答by Peter Olson
I don't know how you are expecting array.remove(int)
to behave. There are three possibilities I can think of that you might want.
我不知道你期望array.remove(int)
如何表现。我可以想到您可能想要的三种可能性。
To remove an element of an array at an index i
:
要删除索引处的数组元素i
:
array.splice(i, 1);
If you want to remove every element with value number
from the array:
如果number
要从数组中删除每个具有 value 的元素:
for(var i = array.length - 1; i >= 0; i--) {
if(array[i] === number) {
array.splice(i, 1);
}
}
If you just want to make the element at index i
no longer exist, but you don't want the indexes of the other elements to change:
如果您只想使 index 处的元素i
不再存在,但又不想更改其他元素的索引:
delete array[i];
回答by ujeenator
Edited on 2016 October
2016 年 10 月编辑
- Do it simple, intuitive and explicit (Occam's razor)
- Do it immutable (original array stay unchanged)
- Do it with standard JavaScript functions, if your browser doesn't support them - use polyfill
- 做到简单、直观和明确(奥卡姆剃刀)
- 做不可变的(原始数组保持不变)
- 如果您的浏览器不支持它们,请使用标准的 JavaScript 函数进行操作 -使用 polyfill
In this code example I use "array.filter(...)"function to remove unwanted items from an array. This function doesn't change the original array and creates a new one. If your browser doesn't support this function (e.g. Internet Explorer before version 9, or Firefox before version 1.5), consider using the filter polyfill from Mozilla.
在此代码示例中,我使用“array.filter(...)”函数从数组中删除不需要的项目。此函数不会更改原始数组并创建一个新数组。如果您的浏览器不支持此功能(例如版本 9 之前的 Internet Explorer,或版本 1.5 之前的 Firefox),请考虑使用Mozilla 的过滤器 polyfill。
Removing item (ECMA-262 Edition 5 code aka oldstyle JavaScript)
删除项目(ECMA-262 版本 5 代码又名旧式 JavaScript)
var value = 3
var arr = [1, 2, 3, 4, 5, 3]
arr = arr.filter(function(item) {
return item !== value
})
console.log(arr)
// [ 1, 2, 4, 5 ]
Removing item (ECMAScript 6 code)
删除项目(ECMAScript 6 代码)
let value = 3
let arr = [1, 2, 3, 4, 5, 3]
arr = arr.filter(item => item !== value)
console.log(arr)
// [ 1, 2, 4, 5 ]
IMPORTANTECMAScript 6 "() => {}" arrow function syntax is not supported in Internet Explorer at all, Chrome before 45 version, Firefox before 22 version, and Safari before 10 version. To use ECMAScript 6 syntax in old browsers you can use BabelJS.
重要的ECMAScript 6 "() => {}" 箭头函数语法在 Internet Explorer、45 版之前的 Chrome、22 版之前的 Firefox 和 10 版之前的 Safari 中完全不支持。要在旧浏览器中使用 ECMAScript 6 语法,您可以使用BabelJS。
Removing multiple items (ECMAScript 7 code)
删除多个项目(ECMAScript 7 代码)
An additional advantage of this method is that you can remove multiple items
此方法的另一个优点是您可以删除多个项目
let forDeletion = [2, 3, 5]
let arr = [1, 2, 3, 4, 5, 3]
arr = arr.filter(item => !forDeletion.includes(item))
// !!! Read below about array.includes(...) support !!!
console.log(arr)
// [ 1, 4 ]
IMPORTANT"array.includes(...)" function is not supported in Internet Explorer at all, Chrome before 47 version, Firefox before 43 version, Safari before 9 version, and Edge before 14 version so here is polyfill from Mozilla.
重要事项Internet Explorer、47 版本之前的 Chrome、43 版本之前的 Firefox、9 版本之前的 Safari 和 14 版本之前的 Edge 根本不支持“array.includes(...)”功能,所以这里是来自 Mozilla 的 polyfill。
Removing multiple items (in the future, maybe)
删除多个项目(将来可能)
If the "This-Binding Syntax"proposal is ever accepted, you'll be able to do this:
如果“This-Binding Syntax”提议被接受,你将能够做到这一点:
// array-lib.js
export function remove(...forDeletion) {
return this.filter(item => !forDeletion.includes(item))
}
// main.js
import { remove } from './array-lib.js'
let arr = [1, 2, 3, 4, 5, 3]
// :: This-Binding Syntax Proposal
// using "remove" function as "virtual method"
// without extending Array.prototype
arr = arr::remove(2, 3, 5)
console.log(arr)
// [ 1, 4 ]
Reference
参考
回答by xavierm02
It depends on whether you want to keep an empty spot or not.
这取决于您是否要保留一个空位。
If you do want an empty slot, delete is fine:
如果你确实想要一个空槽,删除就可以了:
delete array[index];
If you don't, you should use the splicemethod:
如果不这样做,则应使用splice方法:
array.splice(index, 1);
And if you need the value of that item, you can just store the returned array's element:
如果您需要该项目的值,您可以只存储返回数组的元素:
var value = array.splice(index, 1)[0];
In case you want to do it in some order, you can use array.pop()
for the last one or array.shift()
for the first one (and both return the value of the item too).
如果您想按某种顺序执行此操作,您可以将其array.pop()
用于最后一个或array.shift()
第一个(并且都返回项目的值)。
And if you don't know the index of the item, you can use array.indexOf(item)
to get it (in a if()
to get one item or in a while()
to get all of them). array.indexOf(item)
returns either the index or -1 if not found.
如果您不知道项目的索引,您可以使用array.indexOf(item)
它来获取它(在 aif()
中获取一个项目或在 awhile()
中获取所有项目)。array.indexOf(item)
如果未找到,则返回索引或 -1。
回答by Ben Lesh
A friend was having issues in Internet Explorer 8and showed me what he did. I told him it was wrong, and he told me he got the answer here. The current top answer will not work in all browsers (Internet Explorer 8 for example), and it will only remove the first occurrence of the item.
一位朋友在Internet Explorer 8 中遇到问题,并向我展示了他的操作。我告诉他这是错误的,他告诉我他在这里得到了答案。当前的最佳答案不适用于所有浏览器(例如 Internet Explorer 8),它只会删除第一次出现的项目。
Remove ALL instances from an array
从数组中删除所有实例
function remove(arr, item) {
for (var i = arr.length; i--;) {
if (arr[i] === item) {
arr.splice(i, 1);
}
}
}
It loops through the array backwards (since indices and length will change as items are removed) and removes the item if it's found. It works in all browsers.
它向后循环遍历数组(因为索引和长度会随着项目的删除而改变),如果找到则删除项目。它适用于所有浏览器。
回答by Sasa
There are two major approaches:
主要有两种方法:
splice():
anArray.splice(index, 1);
delete:
delete anArray[index];
拼接():
anArray.splice(index, 1);
删除:
delete anArray[index];
Be careful when you use delete for an array. It is good for deleting attributes of objects, but not so good for arrays. It is better to use splice
for arrays.
对数组使用 delete 时要小心。它适用于删除对象的属性,但不适用于数组。最好splice
用于数组。
Keep in mind that when you use delete
for an array you could get wrong results for anArray.length
. In other words, delete
would remove the element, but it wouldn't update the value of length property.
请记住,当您使用delete
数组时,您可能会得到错误的结果anArray.length
。换句话说,delete
会删除元素,但不会更新 length 属性的值。
You can also expect to have holes in index numbers after using delete, e.g. you could end up with having indexes 1, 3, 4, 8, 9, and 11 and length as it was before using delete. In that case, all indexed for
loops would crash, since indexes are no longer sequential.
在使用 delete 之后,您还可以预期在索引号中有空洞,例如,您可能最终拥有索引 1、3、4、8、9 和 11 以及使用 delete 之前的长度。在这种情况下,所有索引for
循环都会崩溃,因为索引不再是连续的。
If you are forced to use delete
for some reason, then you should use for each
loops when you need to loop through arrays. As the matter of fact, always avoid using indexed for
loops, if possible. That way the code would be more robust and less prone to problems with indexes.
如果delete
由于某种原因被迫使用,那么for each
在需要遍历数组时应该使用循环。事实上for
,如果可能,请始终避免使用索引循环。这样,代码将更加健壮,并且不太容易出现索引问题。
回答by Zirak
Array.prototype.remByVal = function(val) {
for (var i = 0; i < this.length; i++) {
if (this[i] === val) {
this.splice(i, 1);
i--;
}
}
return this;
}
//Call like
[1, 2, 3, 4].remByVal(3);
Array.prototype.remByVal = function(val) {
for (var i = 0; i < this.length; i++) {
if (this[i] === val) {
this.splice(i, 1);
i--;
}
}
return this;
}
var rooms = ['hello', 'something']
rooms = rooms.remByVal('hello')
console.log(rooms)
回答by slosd
There is no need to use indexOf
or splice
. However, it performs better if you only want to remove one occurrence of an element.
无需使用indexOf
或splice
。但是,如果您只想删除一个元素,它的性能会更好。
Find and move (move):
查找和移动(移动):
function move(arr, val) {
var j = 0;
for (var i = 0, l = arr.length; i < l; i++) {
if (arr[i] !== val) {
arr[j++] = arr[i];
}
}
arr.length = j;
}
Use indexOf
and splice
(indexof):
使用indexOf
和splice
(索引):
function indexof(arr, val) {
var i;
while ((i = arr.indexOf(val)) != -1) {
arr.splice(i, 1);
}
}
Use only splice
(splice):
仅使用splice
(拼接):
function splice(arr, val) {
for (var i = arr.length; i--;) {
if (arr[i] === val) {
arr.splice(i, 1);
}
}
}
Run-times on nodejs for array with 1000 elements (average over 10000 runs):
具有 1000 个元素的数组在 nodejs 上的运行时间(平均超过 10000 次运行):
indexofis approximately 10x slower than move. Even if improved by removing the call to indexOf
in spliceit performs much worse than move.
indexof大约比move慢 10 倍。即使通过删除对indexOf
in splice的调用进行了改进,它的性能也比move差得多。
Remove all occurrences:
move 0.0048 ms
indexof 0.0463 ms
splice 0.0359 ms
Remove first occurrence:
move_one 0.0041 ms
indexof_one 0.0021 ms
回答by amd
This provides a predicate instead of a value.
这提供了一个谓词而不是一个值。
NOTE:it will update the given array, and return the affected rows.
注意:它将更新给定的数组,并返回受影响的行。
Usage
用法
var removed = helper.removeOne(arr, row => row.id === 5 );
var removed = helper.remove(arr, row => row.name.startsWith('BMW'));
Definition
定义
var helper = {
// Remove and return the first occurrence
removeOne: function(array, predicate) {
for (var i = 0; i < array.length; i++) {
if (predicate(array[i])) {
return array.splice(i, 1);
}
}
},
// Remove and return all occurrences
remove: function(array, predicate) {
var removed = [];
for (var i = 0; i < array.length;) {
if (predicate(array[i])) {
removed.push(array.splice(i, 1));
continue;
}
i++;
}
return removed;
}
};
回答by Salvador Dali
You can do it easily with the filtermethod:
您可以使用filter方法轻松完成:
function remove(arrOriginal, elementToRemove){
return arrOriginal.filter(function(el){return el !== elementToRemove});
}
console.log(remove([1, 2, 1, 0, 3, 1, 4], 1));
This removes all elements from the array and also works faster than a combination of slice
and indexOf
.
这消除了来自阵列的所有元素和也工作速度比的组合slice
和indexOf
。