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

这是我知道若要执行此操作的唯一方法︰

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

是否有更好和更简洁的方式来实现此目的?

对堆栈溢出的问题密切相关的这JavaScript 数组中查找项目的最佳办法?地址使用indexOf数组中的查找对象.

2008-10-25 22:14:40
问题评论:

只是测试︰ 您自己的方式是实际上最快的跨浏览器︰ jsperf.com/find-element-in-obj-vs-array/2 (除了预保存在变量中的 a.length) 时使用 (例如,$.inArray) indexOf 是要慢得多

许多答复数组 #indexOf 是您的最佳选择。但如果需要更可以正确地转换为 boolean 类型的值,则使用此︰ ~[1,2,3].indexOf(4)将返回 0 的计算结果为 false,而~[1,2,3].indexOf(3)将返回它的计算结果为 true,则-3。

~是没有要用于将转换为布尔值,该您需要!但在这种情况下要检查是否与-1 相等,该功能可能结束 s oreturn [1,2,3].indexOf(3) === -1;~不是一个二进制文件,它将单独反转值的每一位。

IE9 支持按照w3schools.com/jsref/jsref_indexof_array.asp indexOf()如果旧版本的浏览器更好的方法是将indexOf()函数prototype定义为在 Internet Explorer 中的 Array.indexOf在给定

@Iordvlad [1,2,3].indexOf(4)将实际上返回-1@Mcfedr 指出,为~按位 NOT 运算符,请参阅 ES5 11.4.8。问题在于,由于只有 1, -1的二进制表示形式组成,它的补数为0,其计算结果为 false。任何其他的数字的补充将不为零,因此,则返回 true。因此, ~顺利运行,它通常使用indexOf结合.

回答:

现代浏览器具有Array#indexOf,它可以做到这一点。甚至较新的浏览器有Array#includes,从而完成完全相同,但遗憾的是没有广泛支持可以使用此填充代码支持较旧的浏览器.

jQuery 提供$.inArray,其功能上等效于Array#indexOf.

underscore.js,一个 JavaScript 实用程序库,提供了_.contains(list, value),别名_.include(list, value),这两种使用indexOf内部如果传递一个 JavaScript 数组。

其他一些框架提供了类似的方法︰

请注意,某些框架实现这为函数,而其他人将函数添加到数组的原型。

编译到 JavaScript 的语言

CoffeeScriptin运算符等效于contains:

a = [1, 2, 3, 4]
alert(2 in a)

Dart:

var mylist = [1, 2, 3];
assert(mylist.contains(1));
assert(mylist.indexOf(1) == 0);

MooTools 还有 Array.contains 返回 boolean 类型的值,这听起来像真正的问题。

原型也有Array.include返回布尔值

如果您使用的一个很好的浏览器,您可以只使用array.indexOf(object) != -1

此外,不要使用 indexOf 单独作为条件,因为第一个元素将返回 0,并且将计算为 falsy

inArray是可怕名称的函数,返回的元素和-1的索引,如果它不存在。我期待能返回一个布尔值。

更新︰ @orip 提到在注释中,链接的准则结束 2008 年,因此,结果可能不是适用于新型浏览器。但是,您可能需要它仍支持非现代的浏览器,他们可能尚未更新以来。始终为自己进行测试。

其他人已经说过,循环访问该数组可能是最好的方法,但它已经被证明了不断降低的while循环是最快的方式在 JavaScript 中循环。因此您可能需要重写您的代码,如下所示︰

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

当然,您也可能扩展数组原型︰

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

但要小心︰ stackoverflow.com/questions/237104/javascript-array-containsobj/...

"成熟"是一个强的词。JS 引擎不断改善,以及执行时间测量 3 年前已经很过时了。

我同意 @Damir 的。可能需要更改此示例只是使人盲目复制-粘贴此代码将获取最佳的性能,它们可以使用 indexOf 如果可用,请。

@cbmeeks 是,一定需要治疗。它可能是做for (o in array)通常循环遍历该数组时不应做的一种情况。.

若要执行此操作的最佳方法是检查 [1,2,3].indexOf(1) >-1

indexOf可能,但它的"JavaScript 扩展名为 ecma-262 标准;这种情况下可能无法出现在标准的其他实现。"

示例︰

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

AFAICS microsoft提供某种类型的替代,但可以将类似的功能添加到 Internet Explorer (和其他浏览器不支持indexOf) 中的阵列,希望作为快速的 Google 搜索会显示(例如,此一).

实际上,没有一种 indexOf 扩展的浏览器不支持它链接到 developer.mozilla.org 页面上的实现。

实际上,如果您添加到数组的浏览器不支持它 (即 IE7) 的原型 indexof 他们也尝试遍历数组中的项时,循环访问此函数。大的麻烦。

IE9 现在支持这

b 是此值,则该数组

它将返回truefalse

function(a, b) {
    return !!~a.indexOf(b)
}

我不理解这一部分"!!~".并且我认为这不会在 IE8 中由于 IE8 在 Array 对象中不支持 indexOf()。

"~"是楼层、 反转和数字从 1 中减去的运算符。indexOf 返回-1,如果它失败,这样"~"变成"0"-1。使用"!!"转变成数字 boleans (!!0 === 假)

@Jean-FrancoisHamelin 因此隐含这会让我哭,如果我以往任何时候都必须使用这样的代码

以相同的性能 ! = 1 jsperf.com/indexof 支票

这是代码的一种完全的我不想看到我的代码库中。-1

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

目前它仍是草稿,但可以是polyfilled ,使其在所有浏览器上工作。

不支持 IE 和 Microsfot 边缘 (2015) (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...)

也相关, ES7 兼容性表(看上去像 chrome 现在支持)

请输入您的翻译

How do I check if an array includes an object in JavaScript?

确认取消