问题 如何检查数组是否包含JavaScript中的对象?
找出JavaScript数组是否包含对象的最简洁有效的方法是什么?
这是我知道的唯一方法:
function contains(a, obj) {
for (var i = 0; i < a.length; i++) {
if (a[i] === obj) {
return true;
}
}
return false;
}
有没有更好,更简洁的方法来实现这一目标?
这与Stack Overflow问题密切相关 在JavaScript数组中查找项目的最佳方法? 其中使用的地址寻找数组中的对象 indexOf
。
12586
2017-10-25 22:14
起源
答案:
目前的浏览器有 Array#includes
,确实如此 究竟 那, 获得广泛支持,并有一个 填充工具 对于旧浏览器。
> ['joe', 'jane', 'mary'].includes('jane');
true
你也可以使用 Array#indexOf
,这不是直接的,但不要求Polyfills用于过时的浏览器。
jQuery提供 $.inArray
,这在功能上等同于 Array#indexOf
。
underscore.js,一个JavaScript实用程序库,提供 _.contains(list, value)
别名 _.include(list, value)
,两者都使用 指数 内部如果传递JavaScript数组。
其他一些框架提供了类似的方法:
请注意,某些框架将此实现为函数,而其他框架则将该函数添加到数组原型中。
3650
2017-10-25 23:10
更新:正如@orip在评论中提到的,链接的基准测试是在2008年完成的,因此结果可能与现代浏览器无关。但是,您可能需要它来支持非现代浏览器,因此它们可能尚未更新。总是为自己测试。
正如其他人所说,通过数组的迭代可能是最好的方法,但它 已被证实 减少 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
357
2017-10-25 22:49
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
如果你想,作为一个 快速谷歌搜索显示 (例如, 这个)。
156
2018-01-01 01:40
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 平等算法。这意味着您可以检测数组是否包含a NaN
:
[1, 2, NaN].includes(NaN); // true
也不像 indexOf
, includes
不会跳过缺失的索引:
new Array(5).includes(undefined); // true
目前它仍然是草案但可以 polyfilled使其适用于所有浏览器。
128
2018-03-24 04:59
b
是价值,和 a
是数组。它回来了 true
要么 false
:
function(a, b) {
return a.indexOf(b) != -1
}
96
2017-10-27 00:38
这是一个 JavaScript 1.6兼容 实施 Array.indexOf
:
if (!Array.indexOf)
{
Array.indexOf = [].indexOf ?
function (arr, obj, from) { return arr.indexOf(obj, from); }:
function (arr, obj, from) { // (for IE6)
var l = arr.length,
i = from ? parseInt( (1*from) + (from<0 ? l:0), 10) : 0;
i = i<0 ? 0 : i;
for (; i<l; i++) {
if (i in arr && arr[i] === obj) { return i; }
}
return -1;
};
}
65
2017-09-13 17:32
使用:
function isInArray(array, search)
{
return array.indexOf(search) >= 0;
}
// Usage
if(isInArray(my_array, "my_value"))
{
//...
}
46
2017-08-27 16:45
扩展JavaScript Array
对象是一个非常糟糕的主意,因为您将新属性(您的自定义方法)引入其中 for-in
循环可以破坏现有的脚本。几年前的作者 原型 库必须重新设计他们的库实现才能删除这种东西。
如果您不需要担心与页面上运行的其他JavaScript的兼容性,那就去吧,否则,我会推荐更笨拙但更安全的独立功能解决方案。
38
2017-07-18 14:36
您可以使用 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
这样做的好处是,一旦找到元素就会中止迭代,从而保存不必要的迭代周期。
有一点需要注意的是 some()
在所有js版本中都不存在:(来自网站)
有些被添加到第5版的ECMA-262标准中;就这样吧
可能不存在于标准的所有实现中
您可以在Node.js中使用它而不会出现任何问题。如果您需要支持所有浏览器,那么这个polyfill(来自同一个链接):
if (!Array.prototype.some)
{
Array.prototype.some = function(fun /*, thisArg */)
{
'use strict';
if (this === void 0 || this === null)
throw new TypeError();
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun !== 'function')
throw new TypeError();
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++)
{
if (i in t && fun.call(thisArg, t[i], i, t))
return true;
}
return false;
};
}
33
2018-01-07 12:49
一内胆:
function contains(arr, x) {
return arr.filter(function(elem) { return elem == x }).length > 0;
}
21
2017-12-23 15:59
21
2018-06-15 01:15