如何检查数组是否在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

LEYJim2020/03/09 12:50:03

好的,您只需优化代码即可获得结果!

有很多方法可以做到这一点越来越好,但是我只想获取您的模式并将其应用于JSON.stringify,只需在您的情况下简单地执行以下操作即可:

function contains(a, obj) {
    for (var i = 0; i < a.length; i++) {
        if (JSON.stringify(a[i]) === JSON.stringify(obj)) {
            return true;
        }
    }
    return false;
}
2020/03/09 12:50:03

虽然这array.indexOf(x)!=-1是最简洁的方法(并且十多年来一直受非Internet Explorer浏览器的支持...),但这不是O(1),而是O(N),这很糟糕。如果您的数组不会改变,则可以将其转换为哈希表,然后执行table[x]!==undefined以下操作===undefined

Array.prototype.toTable = function() {
    var t = {};
    this.forEach(function(x){t[x]=true});
    return t;
}

演示:

var toRemove = [2,4].toTable();
[1,2,3,4,5].filter(function(x){return toRemove[x]===undefined})

(不幸的是,尽管您可以创建一个Array.prototype.contains来“冻结”一个数组并将哈希表存储在两行中的this._cache中,但是如果您以后选择编辑数组,则会产生错误的结果。JavaScript的钩子不足让您保持这种状态,例如与Python不同。)

SamEva2020/03/09 12:50:03

如果您反复检查数组中是否存在某个对象,则应考虑一下

  1. 通过在数组中进行插入排序始终将新对象放在正确的位置)来始终保持数组的排序
  2. 使更新对象成为remove + sorted插入操作,并且
  3. 在中使用二进制搜索查找contains(a, obj)
Chloe2020/03/09 12:50:03
function inArray(elem,array)
{
    var len = array.length;
    for(var i = 0 ; i < len;i++)
    {
        if(array[i] == elem){return i;}
    }
    return -1;
} 

如果找到,则返回数组索引;如果找不到,则返回-1

西门乐2020/03/09 12:50:03

如果您使用的是JavaScript 1.6或更高版本(Firefox 1.5或更高版本),则可以使用Array.indexOf否则,我认为您最终将得到与原始代码相似的东西。

村村JinJin2020/03/09 12:50:03
function contains(a, obj) {
    return a.some(function(element){return element == obj;})
}

Array.prototype.some()已在第5版中添加到ECMA-262标准中

伽罗Mandy2020/03/09 12:50:03

单线:

function contains(arr, x) {
    return arr.filter(function(elem) { return elem == x }).length > 0;
}
2020/03/09 12:50:03

扩展JavaScript Array对象是一个非常糟糕的主意,因为您将新属性(您的自定义方法)引入了for-in可能破坏现有脚本的循环中。几年前,原型的作者不得不重新设计其库实现,以删除此类内容。

如果您不必担心与页面上运行的其他JavaScript的兼容性,请坚持下去,否则,我建议您使用更笨拙但更安全的独立功能解决方案。

小卤蛋Near小卤蛋2020/03/09 12:50:03

采用:

function isInArray(array, search)
{
    return array.indexOf(search) >= 0;
}

// Usage
if(isInArray(my_array, "my_value"))
{
    //...
}
神奇Harry2020/03/09 12:50:03

这是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;
        };
}
Jim小胖米亚2020/03/09 12:50:03

开箱即用地思考一下,如果您多次进行此调用,则使用关联数组 Map来使用哈希函数进行查找要高效得多

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map

神奇宝儿2020/03/09 12:50:03

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,如果你希望),作为一个快速谷歌搜索发现(例如,这一个)。

Sam神乐番长2020/03/09 12:50:03

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

目前,它仍然是草稿,但可以对其进行多填充以使其在所有浏览器上均可使用。