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

IT技术 javascript arrays
2021-01-10 14:10:17

有没有一种方法可以从 JavaScript 数组中删除项目?

给定一个数组:

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

我想做类似的事情:

removeItem('seven', ary);

我已经研究过,splice()但只能按位置号删除,而我需要一些东西来按其值删除项目。

6个回答

你可以使用这样的indexOf方法

var index = array.indexOf(item);
if (index !== -1) {
  array.splice(index, 1);
}

注意您需要为 IE8 及以下版本填充它

确保 index!==(-1) ,即 item 存在于数组中,否则您将拼接出数组中的最后一个元素。
2021-03-13 14:10:17
如果与 不同-1最好进行检查以仅拼接,有数百万个选项,明智地选择jsperf.com/not-vs-gt-vs-ge/4
2021-04-02 14:10:17
并在索引不存在的情况下循环 -1
2021-04-03 14:10:17
如果您使用 jquery,您可以使用$.inArray代替indexOf,它是跨浏览器兼容的。
2021-04-09 14:10:17
2021-04-09 14:10:17

一个单线就可以了,

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

// Remove item 'seven' from array
var filteredAry = ary.filter(function(e) { return e !== 'seven' })
//=> ["three", "eleven"]

// In ECMA6 (arrow function syntax):
var filteredAry = ary.filter(e => e !== 'seven')

这利用了JS中的过滤器功能。它在 IE9 及更高版本中受支持。

它的作用(来自文档链接)

filter() 为数组中的每个元素调用一次提供的回调函数,并构造一个新数组,其中包含回调返回强制为 true 的值的所有值。仅对已分配值的数组索引调用回调;不会为已删除或从未分配值的索引调用它。未通过回调测试的数组元素将被简单地跳过,并且不包含在新数组中。

所以基本上,这与所有其他for (var key in ary) { ... }解决方案相同,只是for in从 IE6 开始支持构造。

基本上,过滤器是一种方便的方法,与for in构造(AFAIK)相比,它看起来更好(并且可以链接)。

这真的很简单,@SLaks 提到的警告是它会创建数组的副本,并且不会影响对变量的引用。
2021-03-12 14:10:17
使用@JeffreyRoosendaal 的贡献更新了答案(filter() does not mutate the array on which it is called.来自developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...)。
2021-03-13 14:10:17
请注意,这应该用作array = array.filter(),而不仅仅是array.filter().
2021-03-21 14:10:17
@bamboon 过滤器功能检查元素是否符合条件。该函数对每个元素一一执行,返回时true,结果数组将保留该元素。在 上省略false
2021-03-28 14:10:17
想知道这个美妙的单线并没有得到更多的爱。+1 没有循环。可以使用&&for 值添加任意数量的要删除的值。
2021-03-30 14:10:17

如果不允许添加到本机原型,则这可以是全局函数或自定义对象的方法。它从数组中删除与任何参数匹配的所有项目。

Array.prototype.remove = function() {
    var what, a = arguments, L = a.length, ax;
    while (L && this.length) {
        what = a[--L];
        while ((ax = this.indexOf(what)) !== -1) {
            this.splice(ax, 1);
        }
    }
    return this;
};

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

ary.remove('seven');

/*  returned value: (Array)
three,eleven
*/

使其成为全球性的

function removeA(arr) {
    var what, a = arguments, L = a.length, ax;
    while (L > 1 && arr.length) {
        what = a[--L];
        while ((ax= arr.indexOf(what)) !== -1) {
            arr.splice(ax, 1);
        }
    }
    return arr;
}
var ary = ['three', 'seven', 'eleven'];
removeA(ary, 'seven');


/*  returned value: (Array)
three,eleven
*/

并照顾 IE8 及以下 -

if(!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(what, i) {
        i = i || 0;
        var L = this.length;
        while (i < L) {
            if(this[i] === what) return i;
            ++i;
        }
        return -1;
    };
}
@xorinzor 不, .prototype 属性是跨浏览器的。
2021-03-14 14:10:17
@YonnTrimoreau 还有什么?定义不可枚举的属性Object.defineProperty(Array.prototype, "remove", {enumerable : false});
2021-03-24 14:10:17
为什么人们展示添加到数组原型的示例?堆栈溢出是为了学习良好的实践
2021-03-29 14:10:17
永远不要改变数组原型。有趣的事情开始发生。
2021-04-05 14:10:17
@madeinstefano,一两个会发生的有趣(坏)事情的例子?
2021-04-09 14:10:17

您可以使用underscore.js它真的让事情变得简单。

例如,与此:

var result = _.without(['three','seven','eleven'], 'seven');

并且result['three','eleven']

在您的情况下,您必须编写的代码是:

ary = _.without(ary, 'seven')

它减少了您编写的代码。

嗨,开尔文,我完全同意你的看法。一个人有一个评论,后来他删除了,他说使用像下划线这样的库并不酷,我们不应该接受这样的答案。我试图回答它。
2021-03-23 14:10:17
我从来没有说过不要在其他地方使用图书馆。如果代码看起来更干净,那么我不介意包含一个库。为什么人们使用 jquery ,那么为什么不使用原始 javascript 呢?
2021-04-06 14:10:17
请注意,这不会就地修改数组;相反,将返回一个新数组。
2021-04-08 14:10:17
@vatsal - 因为库开发人员可以专注于使库函数背后的函数快速、简洁和跨浏览器,而我可以专注于我的应用程序及其目的。它节省了我的思考时间,因此我有额外的时间来改进应用程序,而不必担心构成我的应用程序的小功能。已经有人发明了轮子,为什么每次造车都要重新造?
2021-04-09 14:10:17

您可以通过以下两种方式做到这一点:

const arr = ['1', '2', '3', '4'] // we wanna delete number "3"
  1. 第一种方式:

    arr.indexOf('3') !== -1 && arr.splice(arr.indexOf('3'), 1)
    
  2. 第二种方式(ES6)特别没有 mutate

    const newArr = arr.filter(e => e !== '3')