如何检查多个值是否存在于JavaScript数组中

65
所以,我正在使用Jquery,并且有两个数组,都有多个值,我想检查第一个数组中的所有值是否存在于第二个数组中。
例如,示例1...

数组A包含以下值

34, 78, 89

数组B包含以下值

78, 67, 34, 99, 56, 89

这将返回true

...示例2:

数组A包含以下值

34, 78, 89

数组B包含以下值

78, 67, 99, 56, 89

这将返回false

...示例3:

数组A包含以下值

34, 78, 89

数组B包含以下值

78, 89

这将返回false

到目前为止,我已经尝试通过以下方式解决此问题:

  1. 使用自定义“compare”方法扩展Jquery以比较两个数组。问题在于,当数组完全相同时,这只会返回true,正如您从示例1中看到的,我希望它能够返回true,即使它们不完全相同,但至少包含该值。
  2. 使用Jquerys .inArray函数,但这仅检查数组中的一个值,而不是多个。

任何人都可以提供的任何信息都将非常有用。

11个回答

114

原生 JavaScript 解决方案

var success = array_a.every(function(val) {
    return array_b.indexOf(val) !== -1;
});

如果你要支持旧版浏览器,包括IE8,那么你需要为everyindexOf准备兼容补丁。


完整的jQuery解决方案

var success = $.grep(array_a, function(v,i) {
    return $.inArray(v, array_b) !== -1;
}).length === array_a.length;

使用$.grep$.inArray


ES2015 解决方案

可以使用 ES2015 的箭头函数语法和 .includes() 方法简化上述本地解决方案:

let success = array_a.every((val) => array_b.includes(val))

i(索引)变量未使用且不需要(至少对于JS解决方案而言)。 - jpoppe
1
@jpoppe:是的,那个参数可以省略。我的回答是社区维基,所以请随意进行改进和补充,只要原始意图得到尊重即可。 - user1106925
很棒,ES6解决方案+1 - James Barrett

61
function containsAll(needles, haystack){ 
  for(var i = 0; i < needles.length; i++){
     if($.inArray(needles[i], haystack) == -1) return false;
  }
  return true;
}

containsAll([34, 78, 89], [78, 67, 34, 99, 56, 89]); // true
containsAll([34, 78, 89], [78, 67, 99, 56, 89]); // false
containsAll([34, 78, 89], [78, 89]); // false

9
本地解决方案更好。 - andygoestohollywood

55

用一行代码测试arr1中的所有元素是否都存在于arr2中...

使用ES6:

var containsAll = arr1.every(i => arr2.includes(i));

没有es6:

var containsAll = arr1.every(function (i) { return arr2.includes(i); });

17

我注意到问题是关于使用jQuery解决的,但如果有其他人不局限于jQuery,则可以使用underscore js来解决这个简单的问题。

使用underscore js,您可以执行:

_.intersection(ArrayA, ArrayB).length === ArrayA.length;

来自文档:

intersection_.intersection(*arrays) 计算所有数组的交集值列表。结果中的每个值都出现在所有数组中。

_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]); => [1, 2]

因此,如果ArrayA中有任何一个项在ArrayB中不存在,则交集比ArrayA短。


5
你可以使用一个 Set,并将所有项与其进行比较。

const
    containsAll = (needles, haystack) =>
        needles.every(Set.prototype.has, new Set(haystack));

console.log(containsAll([105, 112, 103], [106, 105, 103, 112]));


2
您可以像这样向数组原型添加containsAll方法:

您可以像这样向数组原型添加containsAll方法:

Array.prototype.containsAll = function()
{
    return Array.from(arguments).every(i => this.includes(i));
}

示例:

["apple", "banana", "strawberry"].containsAll("apple", "banana"); // true

["apple", "banana", "strawberry"].containsAll("apple", "kiwi"); // false

如果有人需要相反的东西:return Array.from(arguments).some(i => this.includes(i));。现在你可以将 containsAll 改为 has :) - Kasir Barati

2

仅仅为了好玩,我使用Array.prototype.reduce()实现了一些东西:

let areKeysPresent = function (sourceArray, referenceArray) {
    return sourceArray.reduce((acc, current) => acc & referenceArray.includes(current), true)
}

0
你可以使用这个简单的函数(根据上面的答案重命名变量以便更容易阅读):
function contains(haystack, needles) {

    return needles.map(function (needle) { 
        return haystack.indexOf(needle);
    }).indexOf(-1) == -1;
}

0

试一试。

var arr1 = [34, 78, 89];
var arr2 = [78, 67, 34, 99, 56, 89];

var containsVal = true;
$.each(arr1, function(i, val){
   if(!$.inArray(val, arr2) != -1){
       retVal = false;
       return false;
   }
});

if(containsVal){
    //arr2 contains all the values from arr1 
}

0
如果你需要更清楚地知道数组中有哪些项,你可以使用这个:
var tools = {
        elem : {},
        arrayContains : function(needles, arrhaystack) {
           if (this.typeOf(needles) === 'array') {
                needle.reduce(function(result,item,$i,array){ // You can use any other way right there.
                    var present = (arrhaystack.indexOf(item) > -1);
                    Object.defineProperty(tools.elem, item, {
                        value : present,
                        writable : true
                    });
                },{})
                return this.elem;
            }
        },        
        typeOf : function(obj) {
            return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
        }
    }

只需使用 var check = tools.arrayContains([10,'foo'], [1,'foo','bar'])

然后您会得到以下结果

10 : false
foo : true

如果你只需要在其中一个为真时获取一个结果,可以这样做:

arr = Object.values(check);
(arr.indexOf('true')) ? instru1 : instru2 ;

我不认为这是更好的方式,但它可以工作并且容易适应。 考虑到这个例子,我建议在你使用它之前先创建一个Object.create(tools)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接