Answers:
使用查找index
要删除的数组元素的indexOf
,然后使用删除该索引splice
。
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);
的第二个参数splice
是要删除的元素数。请注意,splice
将在适当位置修改数组并返回一个包含已删除元素的新数组。
出于完整性的原因,这里有一些功能。第一个功能仅删除单个匹配项(即,5
从中删除第一个匹配项[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;
}
array.indexOf(testValue)
空数组上的值将为-1,并且如果您要对此进行测试,则不进行拼接。此后答案可能已经改变。
我不知道你的array.remove(int)
表现如何。我可以想到您可能想要的三种可能性。
要在索引处删除数组的元素i
:
array.splice(i, 1);
如果number
要从数组中删除每个具有值的元素:
for(var i = array.length - 1; i >= 0; i--) {
if(array[i] === number) {
array.splice(i, 1);
}
}
如果只想使索引处的元素i
不再存在,但又不想更改其他元素的索引:
delete array[i];
delete
不是从数组中删除元素的正确方法!
array.hasOwnProperty(i)
返回false
并在该位置上具有element的地方起作用undefined
。但是我承认这不是一件很普通的事情。
delete
不会更新数组的长度,也不会真正擦除元素,只会将其替换为特殊值undefined
。
undefined
:它还删除了索引和数组中的值,即在之后delete array[0]
,"0" in array
将返回false。
delete
做的人了解为什么它无法按预期工作。
在此代码示例中,我使用“ array.filter(...)”函数从数组中删除不需要的项。此函数不会更改原始数组,而是创建一个新数组。如果您的浏览器不支持此功能(例如,版本9之前的Internet Explorer或版本1.5之前的Firefox),请考虑使用Mozilla中的过滤器polyfill。
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 ]
let value = 3
let arr = [1, 2, 3, 4, 5, 3]
arr = arr.filter(item => item !== value)
console.log(arr)
// [ 1, 2, 4, 5 ]
重要信息 ECMAScript 6的箭头函数语法完全不支持Internet Explorer,45之前的Chrome,22之前的Firefox和10之前的Safari。要在旧的浏览器中使用ECMAScript 6语法,可以使用BabelJS。
此方法的另一个优点是您可以删除多个项目
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 ]
重要提示 “ array.includes(...)”功能在Internet Explorer,47之前的Chrome,43之前的Firefox,9之前的Safari和14之前的Edge中完全不受支持,因此这里是Mozilla的polyfill。
如果“此绑定语法”提议曾经被接受,则可以执行以下操作:
// 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 ]
参考
filter
大阵列一定要慢得多吗?
filter
可能会降低性能,但却是更安全,更好的代码。另外,您可以通过在lambda中指定第二个参数来按索引进行过滤:arr.filter((x,i)=>i!==2)
这取决于您是否要保留空白点。
如果您确实想要一个空插槽,则可以删除:
delete array[index];
如果不这样做,则应使用splice方法:
array.splice(index, 1);
而且,如果您需要该项目的值,则可以只存储返回的数组的元素:
var value = array.splice(index, 1)[0];
如果您想按某种顺序进行操作,则可以将其array.pop()
用于最后一个或array.shift()
第一个(并且两者也都返回该项目的值)。
而且,如果您不知道该项目的索引,则可以使用array.indexOf(item)
获取它(在if()
中获取一个项目或在while()
中获取所有项目)。array.indexOf(item)
返回索引或-1(如果找不到)。
delete
不是从数组中删除元素的正确方法!
array[index] = undefined;
。使用delete
会破坏优化。
一个朋友在Internet Explorer 8中遇到问题,向我展示了他的工作。我告诉他这是错误的,他告诉我他在这里得到了答案。当前的最佳答案不能在所有浏览器(例如Internet Explorer 8)中都有效,并且只会删除该项目的第一个匹配项。
function remove(arr, item) {
for (var i = arr.length; i--;) {
if (arr[i] === item) {
arr.splice(i, 1);
}
}
}
它向后循环遍历数组(因为索引和长度会随着项目的删除而改变),并在找到后删除该项目。它适用于所有浏览器。
i = arr.length -1
或i--
与max索引相同。arr.length
只是的初始值i
。i--
将始终是真实的(并在每个循环op处减少1),直到等于0
(虚假值),然后循环将停止。
arr.filter(function (el) { return el !== item })
,避免多次更改数组的需要。由于只需要做较少的工作,因此会消耗更多的内存,但操作效率更高。
有两种主要方法:
splice():anArray.splice(index, 1);
删除:delete anArray[index];
对数组使用delete时要小心。这对删除对象的属性很有用,但对数组却不太好。最好splice
用于数组。
请记住,当您使用delete
数组时,可能会得到错误的结果anArray.length
。换句话说,delete
将删除该元素,但不会更新length属性的值。
您还可以期望在使用delete后索引号中出现空洞,例如,最终可能会具有使用delete之前的索引1、3、4、8、9、11和长度。在这种情况下,所有索引for
循环都会崩溃,因为索引不再是顺序的。
如果delete
由于某种原因而被迫使用,则for each
在需要遍历数组时应使用循环。实际上for
,如果可能,请始终避免使用索引循环。这样,代码将更健壮,并且不易出现索引问题。
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)
for in
对阵列进行操作,则已经有问题。
for in
对阵列进行操作,则已经存在更大的问题。
无需使用indexOf
或splice
。但是,如果只想删除一个元素,它的性能会更好。
查找并移动(移动):
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;
}
使用indexOf
和splice
(indexof):
function indexof(arr, val) {
var i;
while ((i = arr.indexOf(val)) != -1) {
arr.splice(i, 1);
}
}
仅使用splice
(拼接):
function splice(arr, val) {
for (var i = arr.length; i--;) {
if (arr[i] === val) {
arr.splice(i, 1);
}
}
}
在具有1000个元素的数组的nodejs上的运行时(平均运行10000次以上):
indexof大约比move慢10倍。即使除去调用改进indexOf
的拼接它的性能比更糟糕的举动。
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
这提供了谓词而不是值。
注意:它将更新给定的数组,并返回受影响的行。
var removed = helper.removeOne(arr, row => row.id === 5 );
var removed = helper.remove(arr, row => row.name.startsWith('BMW'));
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;
}
};
您可以使用filter方法轻松完成此操作:
function remove(arrOriginal, elementToRemove){
return arrOriginal.filter(function(el){return el !== elementToRemove});
}
console.log(remove([1, 2, 1, 0, 3, 1, 4], 1));
这消除了来自阵列的所有元素和也工作速度比的组合slice
和indexOf
。
John Resig 发布了一个很好的实现:
// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
var rest = this.slice((to || from) + 1 || this.length);
this.length = from < 0 ? this.length + from : from;
return this.push.apply(this, rest);
};
如果您不想扩展全局对象,则可以执行以下操作:
// Array Remove - By John Resig (MIT Licensed)
Array.remove = function(array, from, to) {
var rest = array.slice((to || from) + 1 || array.length);
array.length = from < 0 ? array.length + from : from;
return array.push.apply(array, rest);
};
但是,我发布此消息的主要原因是为了警告用户不要该页面的注释(2007年12月14日)中建议的替代实现:
Array.prototype.remove = function(from, to){
this.splice(from, (to=[0,from||1,++to-from][arguments.length])<0?this.length+to:to);
return this.length;
};
一开始它似乎运行良好,但是经过一个痛苦的过程,我发现在尝试删除数组中倒数第二个元素时它失败了。例如,如果您有一个包含10个元素的数组,并尝试使用此元素删除第9个元素:
myArray.remove(8);
您最终得到一个8元素数组。不知道为什么,但是我确认John的原始实现没有这个问题。
Object.prototype.hasOwnProperty
总是使用¬¬ 是个好主意
Underscore.js可用于解决多个浏览器的问题。如果存在,它将使用内置浏览器方法。如果缺少它们(例如在较旧的Internet Explorer版本中),则使用其自己的自定义方法。
一个简单的示例(从网站上)从数组中删除元素:
_.without([1, 2, 1, 0, 3, 1, 4], 0, 1); // => [2, 3, 4]
您可以使用ES6。例如,在这种情况下删除值“ 3”:
var array=['1','2','3','4','5','6']
var newArray = array.filter((value)=>value!='3');
console.log(newArray);
输出:
["1", "2", "4", "5", "6"]
查看此代码。它适用于所有主流浏览器。
remove_item = function (arr, value) {
var b = '';
for (b in arr) {
if (arr[b] === value) {
arr.splice(b, 1);
break;
}
}
return arr;
}
调用此功能
remove_item(array,value);
for in
-loop之外,还可以通过直接从循环中返回结果来使脚本更早停止。投票是合理的;)
for( i = 0; i < arr.length; i++ )
将是一种更好的方法,因为它保留了精确的索引,而不是浏览器决定存储项目的顺序(带有for in
)。这样做还可以让您在需要时获取值的数组索引。
您可以使用lodash的_.pull(变异数组),_。pullAt(变异数组)或_.without(不变异数组),
var array1 = ['a', 'b', 'c', 'd']
_.pull(array1, 'c')
console.log(array1) // ['a', 'b', 'd']
var array2 = ['e', 'f', 'g', 'h']
_.pullAt(array2, 0)
console.log(array2) // ['f', 'g', 'h']
var array3 = ['i', 'j', 'k', 'l']
var newArray = _.without(array3, 'i') // ['j', 'k', 'l']
console.log(array3) // ['i', 'j', 'k', 'l']
ES6且无突变:(2016年10月)
const removeByIndex = (list, index) =>
[
...list.slice(0, index),
...list.slice(index + 1)
];
output = removeByIndex([33,22,11,44],1) //=> [33,11,44]
console.log(output)
filter
呢?array.filter((_, index) => index !== removedIndex);
。
从数组中删除特定的元素/字符串可以用一种方法完成:
theArray.splice(theArray.indexOf("stringToRemoveFromArray"), 1);
哪里:
theArray:要从中删除特定内容的数组
stringToRemoveFromArray:要删除的字符串,1是要删除的元素数量。
注意:如果“ stringToRemoveFromArray”不在数组中,则这将删除数组的最后一个元素。
在删除元素之前,先检查该元素是否存在于数组中始终是一个好习惯。
if (theArray.indexOf("stringToRemoveFromArray") >= 0){
theArray.splice(theArray.indexOf("stringToRemoveFromArray"), 1);
}
如果您可以在客户端计算机上访问较新的Ecmascript版本(警告,在较旧的工作站上可能无法使用):
var array=['1','2','3','4','5','6']
var newArray = array.filter((value)=>value!='3');
其中“ 3”是要从数组中删除的值。该数组将变为:['1','2','4','5','6']
"stringToRemoveFromArray"
不在数组中,则将删除数组的最后一个元素。
这是使用JavaScript从数组中删除项目的几种方法。
所描述的所有方法都不会改变原始数组,而是创建一个新数组。
假设您有一个数组,并且想删除position中的项目i
。
一种方法是使用slice()
:
const items = ['a', 'b', 'c', 'd', 'e', 'f']
const i = 3
const filteredItems = items.slice(0, i).concat(items.slice(i+1, items.length))
console.log(filteredItems)
slice()
使用接收到的索引创建一个新数组。我们只需创建一个新数组,即从开始到要删除的索引,然后将第一个数组从我们删除的数组之后的第一个位置连接到数组的末尾。
在这种情况下,一个不错的选择是使用filter()
,它提供了一种更具声明性的方法:
const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valueToRemove = 'c'
const filteredItems = items.filter(item => item !== valueToRemove)
console.log(filteredItems)
这将使用ES6箭头功能。您可以使用传统功能来支持较旧的浏览器:
const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valueToRemove = 'c'
const filteredItems = items.filter(function(item) {
return item !== valueToRemove
})
console.log(filteredItems)
或者您可以使用Babel并将ES6代码重新编译回ES5,以使其更易于被旧的浏览器使用,但仍可以在代码中编写现代的JavaScript。
如果要删除多个项目而不是单个项目怎么办?
让我们找到最简单的解决方案。
您可以创建一个函数并删除一系列项目:
const items = ['a', 'b', 'c', 'd', 'e', 'f']
const removeItem = (items, i) =>
items.slice(0, i-1).concat(items.slice(i, items.length))
let filteredItems = removeItem(items, 3)
filteredItems = removeItem(filteredItems, 5)
//["a", "b", "c", "d"]
console.log(filteredItems)
您可以在回调函数中搜索包含项:
const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valuesToRemove = ['c', 'd']
const filteredItems = items.filter(item => !valuesToRemove.includes(item))
// ["a", "b", "e", "f"]
console.log(filteredItems)
splice()
(不要与混淆slice()
)会使原始数组变异,因此应避免使用。
(最初发布在https://flaviocopes.com/how-to-remove-item-from-array/)
好的,例如,您具有以下数组:
var num = [1, 2, 3, 4, 5];
我们要删除数字4。您可以简单地使用以下代码:
num.splice(num.indexOf(4), 1); // num will be [1, 2, 3, 5];
如果要重用此函数,请编写一个可重用的函数,该函数将附加到本机数组函数,如下所示:
Array.prototype.remove = Array.prototype.remove || function(x) {
const i = this.indexOf(x);
if(i===-1)
return;
this.splice(i, 1); // num.remove(5) === [1, 2, 3];
}
但是,如果有下面的数组而不是数组中有[5]个,那又如何呢?
var num = [5, 6, 5, 4, 5, 1, 5];
我们需要一个循环来检查它们,但是更简单,更有效的方法是使用内置的JavaScript函数,因此我们编写了一个使用如下过滤器的函数:
const _removeValue = (arr, x) => arr.filter(n => n!==x);
//_removeValue([1, 2, 3, 4, 5, 5, 6, 5], 5) // Return [1, 2, 3, 4, 6]
此外,还有第三方库(例如Lodash或Underscore)可以帮助您完成此任务。有关更多信息,请查看lodash _.pull,_。pullAt或_.without。
this.splice(num.indexOf(x), 1);
=>this.splice(this.indexOf(x), 1);
我刚接触JavaScript,需要此功能。我只是这样写:
function removeFromArray(array, item, index) {
while((index = array.indexOf(item)) > -1) {
array.splice(index, 1);
}
}
然后,当我想使用它时:
//Set-up some dummy data
var dummyObj = {name:"meow"};
var dummyArray = [dummyObj, "item1", "item1", "item2"];
//Remove the dummy data
removeFromArray(dummyArray, dummyObj);
removeFromArray(dummyArray, "item2");
输出-如预期。[“ item1”,“ item1”]
您可能与我有不同的需求,因此您可以轻松地对其进行修改以适合他们。我希望这可以帮助别人。
如果数组中有复杂的对象,可以使用过滤器吗?在$ .inArray或array.splice不太容易使用的情况下。特别是如果对象在数组中可能很浅。
例如,如果您有一个带有Id字段的对象,并且希望将该对象从数组中删除:
this.array = this.array.filter(function(element, i) {
return element.id !== idToRemove;
});
我想根据ECMAScript 6回答。假设您有一个如下数组:
let arr = [1,2,3,4];
如果要删除像这样的特殊索引2
,请编写以下代码:
arr.splice(2, 1); //=> arr became [1,2,4]
但是,如果您要删除一个特殊项目,3
而又不知道其索引,请执行以下操作:
arr = arr.filter(e => e !== 3); //=> arr became [1,2,4]
提示:请使用箭头函数进行过滤器回调,除非您得到一个空数组。
更新:仅当您无法使用ECMAScript 2015(以前称为ES6)时,才建议使用此方法。如果可以使用它,这里的其他答案将提供更整洁的实现。
这里的要点将解决您的问题,并删除所有出现的参数,而不仅仅是1(或指定值)。
Array.prototype.destroy = function(obj){
// Return null if no objects were found and removed
var destroyed = null;
for(var i = 0; i < this.length; i++){
// Use while-loop to find adjacent equal objects
while(this[i] === obj){
// Remove this[i] and store it within destroyed
destroyed = this.splice(i, 1)[0];
}
}
return destroyed;
}
用法:
var x = [1, 2, 3, 3, true, false, undefined, false];
x.destroy(3); // => 3
x.destroy(false); // => false
x; // => [1, 2, true, undefined]
x.destroy(true); // => true
x.destroy(undefined); // => undefined
x; // => [1, 2]
x.destroy(3); // => null
x; // => [1, 2]
今天(2019-12-09)我在macOS v10.13.6(High Sierra)上针对所选解决方案进行了性能测试。我显示了delete
(A),但是我没有将其与其他方法相比使用,因为它在数组中留下了空白。
结论
array.splice
(C)(对于第二次使用小型阵列的Safari除外)array.slice+splice
(H)是Firefox和Safari最快的不变解决方案;Array.from
(B)在Chrome中最快在测试中,我以不同的方式从数组中删除了中间元素。在A,C的解决方案是原地。的B,d,E,F,G,H的解决方案是不可变的。
包含10个元素的数组的结果
在Chrome中,array.splice
(C)是最快的就地解决方案。的array.filter
(d)是最快的不可变的溶液。最慢的是array.slice
[F]。您可以在此处在机器上执行测试。
包含1.000.000元素的数组的结果
在Chrome中,array.splice
(C)是最快的就地解决方案(delete
(C)相似得很快-但它在阵列中留下了一个空插槽(因此它不执行“完全删除”))。在array.slice-splice
(H)是最快的不可变的溶液。最慢的是array.filter
(D和E)。您可以在此处在机器上执行测试。
浏览器比较:Chrome v78.0.0,Safari v13.0.4和Firefox v71.0.0
您绝对不应更改数组。因为这与功能编程模式相反。您可以创建一个新数组,而无需使用ECMAScript 6方法引用要更改数据的数组filter
。
var myArray = [1, 2, 3, 4, 5, 6];
假设您5
要从数组中删除,只需执行以下操作即可:
myArray = myArray.filter(value => value !== 5);
这将为您提供一个没有要删除的值的新数组。因此结果将是:
[1, 2, 3, 4, 6]; // 5 has been removed from this array
为了进一步理解,您可以阅读Array.filter上的MDN文档。
一种更现代的ECMAScript 2015(以前称为Harmony或ES 6)方法。鉴于:
const items = [1, 2, 3, 4];
const index = 2;
然后:
items.filter((x, i) => i !== index);
屈服:
[1, 2, 4]
您可以使用Babel和polyfill服务来确保跨浏览器都很好地支持此功能。
.filter
返回一个新数组,这与从同一数组中删除元素并不完全相同。这种方法的好处是可以将数组方法链接在一起。例如:[1,2,3].filter(n => n%2).map(n => n*n) === [ 1, 9 ]
splice
或slice
。
items= items.filter(x=>x!=3)
。此外,OP没有对大数据集提出任何要求。
您的数组中有1到9,并且要删除5。使用以下代码:
var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var newNumberArray = numberArray.filter(m => {
return m !== 5;
});
console.log("new Array, 5 removed", newNumberArray);
如果要多个值。范例:-1,7,8
var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var newNumberArray = numberArray.filter(m => {
return (m !== 1) && (m !== 7) && (m !== 8);
});
console.log("new Array, 1,7 and 8 removed", newNumberArray);
如果要删除数组中的数组值。范例:[3,4,5]
var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var removebleArray = [3,4,5];
var newNumberArray = numberArray.filter(m => {
return !removebleArray.includes(m);
});
console.log("new Array, [3,4,5] removed", newNumberArray);
包括受支持的浏览器是link。
我知道已经有很多答案,但是其中许多似乎使问题变得过于复杂。这是删除键的所有实例的一种简单的递归方法-调用self直到找不到索引。是的,它仅适用于带有indexOf
,但它很简单并且可以轻松地进行填充。
单机功能
function removeAll(array, key){
var index = array.indexOf(key);
if(index === -1) return;
array.splice(index, 1);
removeAll(array,key);
}
原型法
Array.prototype.removeAll = function(key){
var index = this.indexOf(key);
if(index === -1) return;
this.splice(index, 1);
this.removeAll(key);
}
如果该元素存在多个实例,则可以进行向后循环以确保不破坏索引。
var myElement = "chocolate";
var myArray = ['chocolate', 'poptart', 'poptart', 'poptart', 'chocolate', 'poptart', 'poptart', 'chocolate'];
/* Important code */
for (var i = myArray.length - 1; i >= 0; i--) {
if (myArray[i] == myElement) myArray.splice(i, 1);
}