如何通过值从数组中删除项目?

1368

有没有一种方法可以从 JavaScript 数组中移除一个元素?

给定一个数组:

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

我想要做类似这样的事情:

removeItem('seven', ary);

我研究了splice(),但那只能按位置号删除,我需要一种可以按值删除项目的方法。


123
Array.filter() 翻译为 "数组过滤",它是 JavaScript 中的一个数组方法。该方法可用于创建一个新数组,其中包含原始数组中满足特定条件的所有元素。使用该方法需要提供一个回调函数,该函数接受三个参数:当前元素、元素索引和数组本身。回调函数应返回一个布尔值,指示当前元素是否应包含在新数组中。 - Eric Hodonsky
它也可以在这里找到:https://dev59.com/CG025IYBdhLWcg3w1ZoL#21408685这是基准测试:https://jsperf.com/array-without-benchmark-against-lodash - Ardi
我认为从数组中删除元素的最干净的方法是使用数组的ary.filter()方法。ary.filter(val => val !== 'seven')。这将返回一个新数组,其中包含除了“seven”之外的所有元素。 - Ali Raza
ary.splice(ary.indexOf(ID),1)只需使用这个简单的代码行就可以完成! - undefined
显示剩余3条评论
37个回答

33
var index = array.indexOf('item');

if(index!=-1){

   array.splice(index, 1);
}

19

4
这不会改变数组。 - SLaks
9
不会;这会将变量指向一个新的对象。如果您有对原始数组的其他引用,它们不会受到影响。 - SLaks

19
如果你有唯一的值且顺序不重要,使用 Set。 它拥有 delete() 方法:
var mySet = new Set(['three', 'seven', 'eleven']);
mySet.delete('seven'); // Returns true, successfully removed    
[...mySet];            // Returns ['three', 'eleven']

18

ES6方式。

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

我认为JavaScript中的mapreduce函数非常快,但splice仍然更快。因此,更好的实现可能是const removeArrayItem = (arr, itemToRemove) => { return arr.includes(itemToRemove)? arr.splice(arr.indexOf(itemToRemove), 1): arr } - roberto tomás
7
我更注重可读性,而非微小的性能提升。 - Oliver Dixon
嘿@OliverDixon,你能否解释一下comment.Id !== commentId?现在我想删除的评论是5,在过滤器中5 !== 5是false,那么如何删除它呢?:? - Oliver D
1
如果你需要性能,你可以将那段难以理解的代码封装到自己可读的函数中。 - rpgs_player

15

当你需要从数组中删除多次出现的值时(例如 [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]
您可以使用splice从数组中删除单个元素,但splice无法从数组中删除多个相似的元素。
您可以使用splice方法从数组中删除一个元素,但是如果您需要从数组中删除多个相似的元素,splice方法将不再适用。
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]

1
你应该考虑给你的代码添加一些解释。 - Zenoo
1
第5行应该是 removeFrmArr(exampleArray, 3);,当前代码会抛出 ReferenceError。 - mikiqex

15

实际上,我不明白为什么这个问题不能用

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

或者您想使用原生JS

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

可能是因为它没有从数组中移除该项? - Bernardo Dal Corno
1
是的,它不会改变原数组,而是创建一个新的数组,其中不包含字符串“seven”。 - rbenvenuto
1
它对我有效,谢谢。arr = arr.filter(value => value !== 'seven'); - awariat

14

由于没有一个漂亮的,这里有一个简单且可重复使用的ES6函数。

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

用法:

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

4
removeArrayItem 方法并不会从数组中删除元素。它会创建一个新的数组,但不包含该元素。 - WebBrother
正确的@WebBrother。从“消费者”的角度来看,实现并不是我真正关心的问题 - 如果我给它一个数组和一个项目,我会得到一个删除了该项目的数组,因此名称对我有意义。你有什么想法? - Shakespeare
如果你要使用ES6,请确保你使用正确的比较方式(避免使用"!==",而应该使用"!Object.is(item, itemToRemove)")。 - Sterling Bourne

7
从数组中删除所有匹配的元素(而不仅仅是第一个,因为这似乎是这里最常见的答案):
while ($.inArray(item, array) > -1) {
    array.splice( $.inArray(item, array), 1 );
}

我使用了jQuery来完成较重的工作,但是如果你想使用本地语言,你可以得到类似的结果。


4
如果找到该项,您会运行 $.inArray 两次,为什么不在第一次运行时将索引存储起来并重复使用呢?#高效编程 #资源有限。while((index=$.inArray(item,array))>-1) array.splice(index,1); - patrick

7
在所有值唯一的情况下,您可以:
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]

6

一个非常简洁的解决方案,适用于所有浏览器,且不需要任何框架,就是创建一个新的数组,并在返回时删除你想要删除的元素:

/**
 * @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;
}

对于一个干净的解决方案,点赞。太多的答案倾向于建议使用第三方资源,而有时我们需要更纯粹的解决方案(它们都很好,只是不适用于所有情况)。 - Trevor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接