简体   繁体   English

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

[英]How to check whether multiple values exist within an Javascript array

So, I'm using Jquery and have two arrays both with multiple values and I want to check whether all the values in the first array exist in the second.所以,我正在使用 Jquery 并且有两个数组都有多个值,我想检查第一个数组中的所有值是否存在于第二个数组中。

For instance, example 1...例如,示例 1...

Array A contains the following values数组 A 包含以下值

34, 78, 89 34, 78, 89

Array B contains the following values数组 B 包含以下值

78, 67, 34, 99, 56, 89 78, 67, 34, 99, 56, 89

This would return true这将返回true

...example 2: ...示例 2:

Array A contains the following values数组 A 包含以下值

34, 78, 89 34, 78, 89

Array B contains the following values数组 B 包含以下值

78, 67, 99, 56, 89 78, 67, 99, 56, 89

This would return false这将返回false

...example 3: ...示例 3:

Array A contains the following values数组 A 包含以下值

34, 78, 89 34, 78, 89

Array B contains the following values数组 B 包含以下值

78, 89 78, 89

This would return false这将返回false

So far I have tried to solve this by:到目前为止,我已尝试通过以下方式解决此问题:

  1. Extending Jquery with a custom 'compare' method to compare the two arrays. 使用自定义“比较”方法扩展Jquery以比较两个数组。 Problem is this only returns true when the arrays are identical and as you can see from example 1 I want it to return true even if they aren't identical but at least contain the value问题是这仅在数组相同时返回true ,正如您从示例 1 中看到的那样,即使它们不相同但至少包含值,我也希望它返回 true
  2. using Jquerys .inArray function , but this only checks for one value in an array, not multiple.使用Jquerys .inArray 函数,但这只会检查数组中的一个值,而不是多个值。

Any light that anyone could throw on this would be great.任何人都可以抛出的任何灯都会很棒。

Native JavaScript solution原生 JavaScript 解决方案

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

You'll need compatibility patches for every and indexOf if you're supporting older browsers, including IE8.你需要的兼容性补丁everyindexOf如果你支持旧的浏览器,包括IE8。


Full jQuery solution完整的jQuery解决方案

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

Uses $.grep with $.inArray .$.grep$.inArray


ES2015 Solution ES2015 解决方案

The native solution above can be shortened using ES2015's arrow function syntax and its .includes() method:上面的原生解决方案可以使用 ES2015 的箭头函数语法及其.includes()方法来缩短:

let success = array_a.every((val) => array_b.includes(val))
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

A one-liner to test that all of the elements in arr1 exist in arr2 ...用于测试arr1中的所有元素是否存在于arr2中的arr2 ...

With es6:使用es6:

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

Without es6:没有es6:

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

I noticed that the question is about solving this with jQuery, but if anyone else who is not limited to jQuery comes around then there is a simple solution using underscore js.我注意到这个问题是关于用 jQuery 解决这个问题的,但是如果不限于 jQuery 的其他人出现,那么有一个使用下划线 js 的简单解决方案。

Using underscore js you can do:使用下划线 js,您可以执行以下操作:

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

From the docs:从文档:

intersection_.intersection(*arrays) Computes the list of values that are the intersection of all the arrays. intersection_.intersection(*arrays) 计算作为所有数组交集的值列表。 Each value in the result is present in each of the arrays.结果中的每个值都存在于每个数组中。

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

Ergo, if one of the items in ArrayA was missing in ArrayB, then the intersection would be shorter than ArrayA.因此,如果 ArrayA 中的一项在 ArrayB 中丢失,则交集将比 ArrayA 短。

You could take a Set and check all items agains it.你可以拿一个Set并再次检查所有项目。

 const containsAll = (needles, haystack) => needles.every(Set.prototype.has, new Set(haystack)); console.log(containsAll([105, 112, 103], [106, 105, 103, 112]));

If you need a little bit more visibility on which items are in the array you can use this one :如果您需要更多地了解数组中的哪些项目,您可以使用这个:

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

Use it with simply var check = tools.arrayContains([10,'foo'], [1,'foo','bar'])简单地使用它var check = tools.arrayContains([10,'foo'], [1,'foo','bar'])

Then you get the result like然后你会得到这样的结果

10 : false
foo : true

Then if you need to get only one result if one of them is true you can :然后,如果您只需要获得一个结果(如果其中之一为真),您可以:

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

I don't think that's the better way but it's working & easily adaptable.我不认为这是更好的方法,但它有效且易于适应。 Considering this example I advise you to make an Object.create(tools) before use it in your way.考虑到这个例子,我建议你在以你的方式使用它之前制作一个Object.create(tools)

Using array functions: [].filter and [].includes使用数组函数: [].filter[].includes

Something like this:像这样的东西:

[34, 78, 89].filter((v) => {
    return [78, 67, 34, 99, 56, 89].includes(v);
});

This will return an array of the matches items这将返回匹配项的数组

Then we can compare it with needles array然后我们可以将它与needles数组进行比较

As a function it will be:作为一个函数,它将是:

const contains = (haystack, needles) => {
    return haystack.filter((v) => {
        return needles.includes(v);
    }).length === needles.length;
}

Just for the fun of it, i've implemented something with Array.prototype.reduce() :只是为了好玩,我用 Array.prototype.reduce() 实现了一些东西:

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

You could also add a containsAll to Array prototype like this:你也可以像这样添加一个 containsAll 到 Array 原型:

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

Examples:例子:

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

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

You can use this simple function (renamed variables as per above answer for easy reading):您可以使用这个简单的函数(按照上面的答案重命名变量以便于阅读):

function contains(haystack, needles) {

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

Try this.试试这个。

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 
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM