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

这是我知道的唯一方法:

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

有没有更好、更简洁的方法来实现这一点?

这与堆栈溢出问题密切相关。在JavaScript数组中查找项目的最佳方法是什么?它解决了使用indexOf查找数组中的对象的问题。


当前回答

我查看了提交的答案,发现只有通过引用搜索对象时,这些答案才适用。具有参考对象比较的简单线性搜索。

但是,假设您没有对象的引用,如何在数组中找到正确的对象?您必须对每个对象进行线性和深度比较。想象一下,如果列表太大,并且其中的对象非常大,包含大量文本。随着阵列中元素的数量和大小,性能急剧下降。

您可以将对象字符串化并将其放入本机哈希表中,但这样您就有了记住这些键的数据冗余,因为JavaScript将它们保存为“for i in obj”,您只需要检查对象是否存在,也就是说,您拥有该键。

我考虑了一段时间来构建一个JSON模式验证器,我为本地哈希表设计了一个简单的包装器,类似于唯一的哈希表实现,但一些优化异常我留给本地哈希表处理。它只需要性能基准。。。所有详细信息和代码都可以在我的博客上找到:http://stamat.wordpress.com/javascript-quickly-find-very-large-objects-in-a-large-array/我将很快发布基准结果。

完整的解决方案如下所示:

var a = {'a':1,
 'b':{'c':[1,2,[3,45],4,5],
 'd':{'q':1, 'b':{'q':1, 'b':8},'c':4},
 'u':'lol'},
 'e':2};

 var b = {'a':1, 
 'b':{'c':[2,3,[1]],
 'd':{'q':3,'b':{'b':3}}},
 'e':2};

 var c = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.";

 var hc = new HashCache([{a:3, b:2, c:5}, {a:15, b:2, c:'foo'}]); //init

 hc.put({a:1, b:1});
 hc.put({b:1, a:1});
 hc.put(true);
 hc.put('true');
 hc.put(a);
 hc.put(c);
 hc.put(d);
 console.log(hc.exists('true'));
 console.log(hc.exists(a));
 console.log(hc.exists(c));
 console.log(hc.exists({b:1, a:1}));
 hc.remove(a);
 console.log(hc.exists(c));

其他回答

这里是Array.indexOf的JavaScript 1.6兼容实现:

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;
        };
}

使用Array.indexOf(对象)。对于ECMA7,可以使用Array.includes(对象)。使用ECMA 6,可以使用Array.find(FunctionName),其中FunctionName是用户定义函数以搜索数组中的对象。希望这有帮助!

上面的答案假设是基元类型,但如果您想知道数组是否包含具有某种特征的对象,array.protocol.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.protocol.some()是完全支持的:caniuse.com支持表

使用lodash的一些功能。

它简洁、准确,并且具有强大的跨平台支持。

接受的答案甚至不符合要求。

要求:推荐最简洁有效的方法来确定JavaScript数组是否包含对象。

接受答案:

$.inArray({'b': 2}, [{'a': 1}, {'b': 2}])
> -1

我的建议:

_.some([{'a': 1}, {'b': 2}], {'b': 2})
> true

笔记:

$.inArray可以很好地确定标量数组中是否存在标量值。。。

$.inArray(2, [1,2])
> 1

…但这个问题显然需要一种有效的方法来确定数组中是否包含对象。

为了处理标量和对象,可以执行以下操作:

(_.isObject(item)) ? _.some(ary, item) : (_.indexOf(ary, item) > -1)

简单的解决方案:ES6功能“包含”方法

let arr = [1, 2, 3, 2, 3, 2, 3, 4];

  arr.includes(2) // true

  arr.includes(93) // false