如何检查数组是否包含 JavaScript 中的值?

IT技术 javascript arrays algorithm time-complexity javascript-objects
2020-12-19 23:24:51

找出 JavaScript 数组是否包含值的最简洁有效的方法是什么?

这是我知道的唯一方法:

function contains(a, obj) {
    for (var i = 0; i < a.length; i++) {
        if (a[i] === obj) {
            return true;
        }
    }
    return false;
}

有没有更好,更简洁的方法来实现这一目标?

6个回答

现代浏览器有Array#includes,它正是这样做的,并且得到了除 IE 之外的所有人的广泛支持

console.log(['joe', 'jane', 'mary'].includes('jane')); //true

您也可以使用Array#indexOf,它不太直接,但不需要为过时的浏览器提供 polyfill。

console.log(['joe', 'jane', 'mary'].indexOf('jane') >= 0); //true


许多框架也提供了类似的方法:

请注意,一些框架将其实现为一个函数,而其他框架则将该函数添加到数组原型中。

如果您使用的是良好的浏览器,则可以使用 array.indexOf(object) != -1
2021-02-15 23:24:51
MooTools 也有 Array.contains 返回一个布尔值,这听起来像是真正的问题。
2021-02-16 23:24:51
inArray对于返回元素索引的函数来说是一个糟糕的名字,-1如果它不存在。我希望返回一个布尔值。
2021-02-18 23:24:51
另外,不要单独使用 indexOf 作为条件,因为第一个元素将返回 0 并被评估为假
2021-02-23 23:24:51
原型也有Array.include返回一个布尔值
2021-03-03 23:24:51

2019 年更新:此答案来自 2008 年(11 岁!),与现代 JS 使用无关。Promise的性能改进基于当时在浏览器中完成的基准测试。它可能与现代 JS 执行上下文无关。如果您需要一个简单的解决方案,请寻找其他答案。如果您需要最佳性能,请在相关执行环境中对自己进行基准测试。

正如其他人所说,通过数组进行迭代可能是最好的方式,但事实证明,递减while循环是 JavaScript 中最快的迭代方式。因此,您可能需要按如下方式重写代码:

function contains(a, obj) {
    var i = a.length;
    while (i--) {
       if (a[i] === obj) {
           return true;
       }
    }
    return false;
}

当然,你也可以扩展Array原型:

Array.prototype.contains = function(obj) {
    var i = this.length;
    while (i--) {
        if (this[i] === obj) {
            return true;
        }
    }
    return false;
}

现在您可以简单地使用以下内容:

alert([1, 2, 3].contains(2)); // => true
alert([1, 2, 3].contains('2')); // => false
“证明”是一个强有力的词。JS 引擎不断改进,3 年前测量的执行时间已经过时了。
2021-02-10 23:24:51

indexOf 也许,但它是“ECMA-262 标准的 JavaScript 扩展;因此它可能不存在于该标准的其他实现中。”

例子:

[1, 2, 3].indexOf(1) => 0
["foo", "bar", "baz"].indexOf("bar") => 1
[1, 2, 3].indexOf(4) => -1

AFAICS微软并没有提供某种替代的这一点,但你可以在Internet Explorer阵列(和不支持其他浏览器加入类似的功能indexOf,如果你希望),作为一个快速谷歌搜索发现(例如,这一个)。

ECMAScript 7 引入了Array.prototype.includes.

它可以像这样使用:

[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false

它还接受可选的第二个参数fromIndex

[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true

不像indexOf,它采用严格相等比较includes比较了使用SameValueZero平等算法。这意味着您可以检测数组是否包含NaN

[1, 2, NaN].includes(NaN); // true

也不同于indexOfincludes不会跳过缺失的索引:

new Array(5).includes(undefined); // true

目前它仍然是一个草案,但可以进行polyfill以使其适用于所有浏览器。

最重要的答案假设原始类型,但如果您想确定数组是否包含具有某些特征对象Array.prototype.some()是一个优雅的解决方案:

const items = [ {a: '1'}, {a: '2'}, {a: '3'} ]

items.some(item => item.a === '3')  // returns true
items.some(item => item.a === '4')  // returns false

这样做的好处是,一旦找到元素,迭代就会中止,从而避免了不必要的迭代周期。

此外,它非常适合用于if语句,因为它返回一个布尔值:

if (items.some(item => item.a === '3')) {
  // do something
}

* 正如 jamess 在评论中指出的那样,在此回答时,2018 年 9 月,Array.prototype.some()完全支持:caniuse.com 支持表