如何从JavaScript中的数组中删除特定的元素?

我有一个整数数组,我使用.push()方法向它添加元素。

有一个简单的方法来从数组中删除一个特定的元素? 相当于类似array.remove(int);

我必须使用核心 JavaScript – 不允许任何框架。

首先,find你想要删除的元素的index

 var array = [2, 5, 9]; var index = array.indexOf(5); 

注意: 浏览器对indexOf的支持是有限的 ; 它在Internet Explorer 7和8中不受支持。

然后用splice删除它:

 if (index > -1) { array.splice(index, 1); } 

splice的第二个参数是要删除的元素的数量。 请注意, splice将修改数组,并返回一个包含已被删除的元素的新数组。


如果您需要在不受支持的浏览器中使用indexOf ,请尝试以下polyfill在这里find关于这个polyfill更多信息。

 Array.prototype.indexOf || (Array.prototype.indexOf = function(d, e) { var a; if (null == this) throw new TypeError('"this" is null or not defined'); var c = Object(this), b = c.length >>> 0; if (0 === b) return -1; a = +e || 0; Infinity === Math.abs(a) && (a = 0); if (a >= b) return -1; for (a = Math.max(0 <= a ? a : b - Math.abs(a), 0); a < b;) { if (a in c && c[a] === d) return a; a++ } return -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]; 

编辑于2016年10月

在这个代码示例中,我使用“array.filter(…)”函数从数组中删除不需要的项目,该函数不会更改原始数组并创build一个新的数组。 如果您的浏览器不支持此function(例如版本9之前的IE或版本1.5之前的Firefox),请考虑使用Mozilla的filter填充

删除项目(ECMA-262版5代码又名oldstyle JS)

 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 ] 

删除项目(ES2015代码)

 let value = 3 let arr = [1, 2, 3, 4, 5, 3] arr = arr.filter(item => item !== value) console.log(arr) // [ 1, 2, 4, 5 ] 

重要 ES2015“()=> {}”箭头函数语法在IE中根本不支持,Chrome前45版本,Firefox前22版本,Safari前10版本。 要在旧版浏览器中使用ES2015语法,您可以使用BabelJS


删除多个项目(ES2015代码)

这种方法的另一个好处是你可以删除多个项目

 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(…)”function在IE中完全不支持,47版之前的Chrome,43版之前的Firefox,9版之前的Safari以及14版之前的Edge,所以这里是来自Mozilla的polyfill

删除多个项目(尖端实验JavaScript ES2018?)

 // 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 ] 

在BabelJS中自己尝试:)

参考

  • Array.prototype.includes
  • 这种绑定语法build议
  • function组成

取决于你是否想保留空位。

如果你想要一个空插槽,删除是好的:

 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。

一位朋友在Internet Explorer 8中遇到了问题,并向我展示了他做了什么。 我告诉他这是错的,他告诉我他在这里得到了答案。 当前最佳答案在所有浏览器(例如Internet Explorer 8)中都不起作用,并且只会删除该项目的第一个匹配项。

从数组中删除所有实例

  function remove(arr, item) { for(var i = arr.length; i--;) { if(arr[i] === item) { arr.splice(i, 1); } } } 

它通过向后循环数组(因为索引和长度将随着项目被移除而改变)并且如果find该项目则移除该项目。 它适用于所有浏览器。

有两种主要方法:

  1. splice()anArray.splice(index, 1);

  2. 删除delete anArray[index];

使用数组删除时要小心。 这对于删除对象的属性是好的,但是对于数组来说不是那么好。 数组使用splice比较好。

请记住,当您使用数组delete ,您可能会得到错误的anArray.length结果。 换句话说, delete将删除元素,但不会更新length属性的值。

你也可以期望在使用删除之后在索引号中有空位,例如,最后可能会使用索引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) 

没有必要使用indexOfsplice 。 但是,如果您只想删除一个元素,它会更好。

查找并移动(移动):

 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; } 

使用indexOfsplice (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大约比移动慢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; } }; 

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元素的数组。 不知道为什么,但我确认约翰原来的执行没有这个问题。

Underscore.js可以用来解决多个浏览器的问题。 如果有的话,它使用内置的浏览器方法。 如果他们不在Internet Explorer版本的情况下使用它自己的自定义方法。

从数组(从网站)中删除元素的简单示例:

 _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); // => [2, 3, 4] 

您可以使用过滤方法轻松完成:

 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更快

如果您想删除已删除位置的新数组,则可以始终删除特定元素并过滤掉数组。 它可能需要一个浏览器的数组对象的扩展没有实现filter的方法,但从长远来看它更容易,因为你所做的是这样的:

 var my_array = [1,2,3,4,5,6]; delete my_array[4]; console.log(my_array.filter(function(a){return typeof a !== 'undefined';})); 

应该显示[1, 2, 3, 4, 6]

看看这个代码。 它适用于所有主stream浏览器

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

你可以使用ES6。

 var array=['1','2','3','4','5','6'] var index = array.filter((value)=>value!='3'); 

输出:

 ["1", "2", "4", "5", "6"] 

您可以使用lodash _.pull (mutate数组), _.pullAt (mutate数组)或_.without ( 不会 mutate数组),

 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'] 

我很新的JavaScript,需要这个function。 我只是写了这个:

 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”]

你可能有不同的需求,所以你可以很容易地修改它,以适应他们。 我希望这可以帮助别人。

如果你在数组中有复杂的对象,你可以使用filter? 在$ .inArray或array.splice不太容易使用的情况下。 特别是如果对象在数组中可能很浅。

例如,如果你有一个Id字段的对象,你想从数组中删除对象:

 this.array = this.array.filter(function(element, i) { return element.id !== idToRemove; }); 

ES6&没有突变:(2016年10月)

 const removeByIndex = (list, index) => [ ...list.slice(0, index), ...list.slice(index + 1) ]; 

然后 :

 removeByIndex([33,22,11,44],1) //=> [33,11,44] 

更现代的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服务来确保跨浏览器的支持。

更新:仅当您不能使用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] 

我知道已经有很多答案了,但是其中很多答案似乎使问题复杂化了。 这是一个简单的,recursion的方法来移除一个键的所有实例 – 调用self直到找不到索引。 是的,它只适用于indexOf浏览器,但它很简单,可以很容易地填充。

独立function

 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); } 

按索引删除

返回索引处没有元素的数组副本的函数。

 /** * removeByIndex * @param {Array} array * @param {Number} index */ function removeByIndex(array, index){ return array.filter(function(elem, _index){ return index != _index; }); } l = [1,3,4,5,6,7]; console.log(removeByIndex(l, 1)); $> [ 1, 4, 5, 6, 7 ] 

按值删除

返回没有Value的数组副本的函数。

 /** * removeByValue * @param {Array} array * @param {Number} value */ function removeByValue(array, value){ return array.filter(function(elem, _index){ return value != elem; }); } l = [1,3,4,5,6,7]; console.log(removeByValue(l, 5)); $> [ 1, 3, 4, 6, 7] 

如果元素有多个实例,则可以执行反向循环以确保不会弄乱索引。

 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); } 

现场演示

使用jQuery的InArray:

 A = [1, 2, 3, 4, 5, 6]; A.splice($.inArray(3, A), 1); //It will return A=[1, 2, 4, 5, 6]` 

注意:如果找不到元素,inArray将返回-1。

创build新的数组:

 var my_array = new Array(); 

添加元素到这个数组:

 my_array.push("element1"); 

函数indexOf(返回索引或未find时为-1):

 var indexOf = function(needle) { if(typeof Array.prototype.indexOf === 'function') // newer browsers { indexOf = Array.prototype.indexOf; } else // older browsers { indexOf = function(needle) { var index = -1; for(var i = 0; i < this.length; i++) { if(this[i] === needle) { index = i; break; } } return index; }; } return indexOf.call(this, needle); }; 

检查这个元素的索引(用firefox和IE8 +testing):

 var index = indexOf.call(my_array, "element1"); 

从数组中删除位于索引处的1个元素

 my_array.splice(index, 1); 
  Array.prototype.removeItem = function(a) { for (i = 0; i < this.length; i++) { if (this[i] == a) { for (i2 = i; i2 < this.length - 1; i2++) { this[i2] = this[i2 + 1]; } this.length = this.length - 1 return; } } } var recentMovies = ['Iron Man', 'Batman', 'Superman', 'Spiderman']; recentMovies.removeItem('Superman'); 

我也遇到了必须从Array删除元素的情况。 .indexOf不工作在IE*所以共享我的工作jQuery.inArray()解决scheme。

 var index = jQuery.inArray(val,arr); if (index > -1) { arr.splice(index, 1); //console.log(arr); } 

我认为许多JavaScript指令在函数式编程中并没有很好的思考。 在大部分时间需要缩小的数组的时候,Splice会返回被删除的元素。 这不好。

想象一下,你正在做一个recursion调用,并且必须传递一个less一个数组的数组,可能没有当前的索引项。 或者想象你正在做另一个recursion调用,并且必须通过一个推送元素的数组。

在这两种情况下,您都可以执行myRecursiveFunction(myArr.push(c))myRecursiveFunction(myArr.splice(i,1)) 。 第一个白痴实际上将传递数组的长度,第二个白痴将通过删除的元素作为参数。

所以我做的事实上…为了删除一个数组元素,并将结果作为一个parameter passing给一个函数,我做了如下

 myRecursiveFunction(myArr.slice(0,i).concat(a.slice(i+1))) 

当谈到推这更愚蠢的…我喜欢,

 myRecursiveFunction((myArr.push(c),myArr)) 

我相信在一个正确的函数式语言中,一个变异的对象的方法必须返回一个对该对象的引用。

2017年5月8日

Most of the given answers work for strict comparison, meaning that both objects reference the exact same object in memory (or are primitive types), but often you want to remove a non-primitive object from an array that has a certain value. For instance, if you make a call to a server and want to check a retrieved object against a local object.

 const a = {'field': 2} // Non-primitive object const b = {'field': 2} // Non-primitive object with same value const c = a // Non-primitive object that reference the same object as "a" assert(a !== b) // Don't reference the same item, but have same value assert(a === c) // Do reference the same item, and have same value (naturally) //Note: there are many alternative implementations for valuesAreEqual function valuesAreEqual (x, y) { return JSON.stringify(x) === JSON.stringify(y) } //filter will delete false values //Thus, we want to return "false" if the item // we want to delete is equal to the item in the array function removeFromArray(arr, toDelete){ return arr.filter(target => {return !valuesAreEqual(toDelete, target)}) } const exampleArray = [a, b, b, c, a, {'field': 2}, {'field': 90}]; const resultArray = removeFromArray(exampleArray, a); //resultArray = [{'field':90}] 

There are alternative/faster implementations for valuesAreEqual, but this does the job. You can also use a custom comparator if you have a specific field to check (for example, some retrieved UUID vs a local UUID).

Also note that this is a functional operation, meaning that it does not mutate the original array.