检查一个数组是否包含 JavaScript 中另一个数组的任何元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16312528/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 04:10:29  来源:igfitidea点击:

Check if an array contains any element of another array in JavaScript

javascriptarrays

提问by Alex

I have a target array ["apple","banana","orange"], and I want to check if other arrays contain any one of the target array elements.

我有一个目标数组["apple","banana","orange"],我想检查其他数组是否包含任何一个目标数组元素。

For example:

例如:

["apple","grape"] //returns true;

["apple","banana","pineapple"] //returns true;

["grape", "pineapple"] //returns false;

How can I do it in JavaScript?

我如何在 JavaScript 中做到这一点?

回答by Paul Grimshaw

Vanilla JS

香草JS

ES2016:

ES2016:

const found = arr1.some(r=> arr2.includes(r))

ES6:

ES6:

const found = arr1.some(r=> arr2.indexOf(r) >= 0)

How it works

怎么运行的

some(..)checks each element of the array against a test function and returns true if any element of the array passes the test function, otherwise, it returns false. indexOf(..) >= 0and includes(..)both return true if the given argument is present in the array.

some(..)根据测试函数检查数组的每个元素,如果数组的任何元素通过测试函数,则返回 true,否则返回 false。如果给定的参数存在于数组中indexOf(..) >= 0,则includes(..)两者都返回 true。

回答by skyisred

vanilla js

香草js

/**
 * @description determine if an array contains one or more items from another array.
 * @param {array} haystack the array to search.
 * @param {array} arr the array providing items to check for in the haystack.
 * @return {boolean} true|false if haystack contains at least one item from arr.
 */
var findOne = function (haystack, arr) {
    return arr.some(function (v) {
        return haystack.indexOf(v) >= 0;
    });
};

回答by willz

If you're not opposed to using a libray, http://underscorejs.org/has an intersection method, which can simplify this:

如果你不反对使用 libray,http://underscorejs.org/有一个交集方法,它可以简化这个:

var _ = require('underscore');

var target = [ 'apple', 'orange', 'banana'];
var fruit2 = [ 'apple', 'orange', 'mango'];
var fruit3 = [ 'mango', 'lemon', 'pineapple'];
var fruit4 = [ 'orange', 'lemon', 'grapes'];

console.log(_.intersection(target, fruit2)); //returns [apple, orange]
console.log(_.intersection(target, fruit3)); //returns []
console.log(_.intersection(target, fruit4)); //returns [orange]

The intersection function will return a new array with the items that it matched and if not matches it returns empty array.

交叉函数将返回一个新数组,其中包含匹配的项目,如果不匹配,则返回空数组。

回答by lusk

ES6 (fastest)

ES6(最快)

const a = ['a', 'b', 'c'];
const b = ['c', 'a', 'd'];
a.some(v=> b.indexOf(v) !== -1)

ES2016

ES2016

const a = ['a', 'b', 'c'];
const b = ['c', 'a', 'd'];
a.some(v => b.includes(v));

Underscore

下划线

const a = ['a', 'b', 'c'];
const b = ['c', 'a', 'd'];
_.intersection(a, b)

DEMO: https://jsfiddle.net/r257wuv5/

演示:https: //jsfiddle.net/r257wuv5/

jsPerf: https://jsperf.com/array-contains-any-element-of-another-array

jsPerf:https://jsperf.com/array-contains-any-element-of-another-array

回答by Ian

If you don't need type coercion (because of the use of indexOf), you could try something like the following:

如果您不需要类型强制(因为使用了indexOf),您可以尝试以下操作:

var arr = [1, 2, 3];
var check = [3, 4];

var found = false;
for (var i = 0; i < check.length; i++) {
    if (arr.indexOf(check[i]) > -1) {
        found = true;
        break;
    }
}
console.log(found);

Where arrcontains the target items. At the end, foundwill show if the second array had at least onematch against the target.

其中arr包含目标项目。最后,found将显示第二个数组是否至少与目标匹配。

Of course, you can swap out numbers for anything you want to use - strings are fine, like your example.

当然,您可以将数字换成您想要使用的任何东西 - 字符串很好,就像您的示例一样。

And in my specific example, the result should be truebecause the second array's 3exists in the target.

在我的具体示例中,结果应该是true因为3目标中存在第二个数组。



UPDATE:

更新:

Here's how I'd organize it into a function (with some minor changes from before):

这是我将它组织成一个函数的方式(与之前的一些小的变化):

var anyMatchInArray = (function () {
    "use strict";

    var targetArray, func;

    targetArray = ["apple", "banana", "orange"];
    func = function (checkerArray) {
        var found = false;
        for (var i = 0, j = checkerArray.length; !found && i < j; i++) {
            if (targetArray.indexOf(checkerArray[i]) > -1) {
                found = true;
            }
        }
        return found;
    };

    return func;
}());

DEMO:http://jsfiddle.net/u8Bzt/

演示:http : //jsfiddle.net/u8Bzt/

In this case, the function could be modified to have targetArraybe passed in as an argument instead of hardcoded in the closure.

在这种情况下,可以将函数修改为targetArray作为参数传入,而不是在闭包中进行硬编码。



UPDATE2:

更新2:

While my solution above may work and be (hopefully more) readable, I believe the "better" way to handle the concept I described is to do something a little differently. The "problem" with the above solution is that the indexOfinside the loop causes the target array to be looped over completely for every item in the other array. This can easily be "fixed" by using a "lookup" (a map...a JavaScript object literal). This allows two simple loops, over each array. Here's an example:

虽然我上面的解决方案可能有效并且(希望更多)可读,但我相信处理我描述的概念的“更好”方法是做一些不同的事情。上述解决方案的“问题”在于,indexOf循环内部导致目标数组针对另一个数组中的每个项目完全循环。这可以通过使用“查找”(地图...JavaScript 对象文字)轻松“修复”。这允许在每个数组上进行两个简单的循环。下面是一个例子:

var anyMatchInArray = function (target, toMatch) {
    "use strict";

    var found, targetMap, i, j, cur;

    found = false;
    targetMap = {};

    // Put all values in the `target` array into a map, where
    //  the keys are the values from the array
    for (i = 0, j = target.length; i < j; i++) {
        cur = target[i];
        targetMap[cur] = true;
    }

    // Loop over all items in the `toMatch` array and see if any of
    //  their values are in the map from before
    for (i = 0, j = toMatch.length; !found && (i < j); i++) {
        cur = toMatch[i];
        found = !!targetMap[cur];
        // If found, `targetMap[cur]` will return true, otherwise it
        //  will return `undefined`...that's what the `!!` is for
    }

    return found;
};

DEMO:http://jsfiddle.net/5Lv9v/

演示:http : //jsfiddle.net/5Lv9v/

The downside to this solution is that only numbers and strings (and booleans) can be used (correctly), because the values are (implicitly) converted to strings and set as the keys to the lookup map. This isn't exactly good/possible/easily done for non-literal values.

此解决方案的缺点是只能(正确)使用数字和字符串(和布尔值),因为这些值(隐式)转换为字符串并设置为查找映射的键。对于非文字值,这不是很好/可能/容易做到。

回答by tanvir993

ES6 solution:

ES6解决方案:

let arr1 = [1, 2, 3];
let arr2 = [2, 3];

let isFounded = arr1.some( ai => arr2.includes(ai) );

Unlike of it: Must contains all values.

与它不同的是:必须包含所有值。

let allFounded = arr2.every( ai => arr1.includes(ai) );

Hope, will be helpful.

希望,会有所帮助。

回答by Vadim Gremyachev

Using filter/indexOf:

使用过滤器/ indexOf

function containsAny(source,target)
{
    var result = source.filter(function(item){ return target.indexOf(item) > -1});   
    return (result.length > 0);  
}    


//results

var fruits = ["apple","banana","orange"];


console.log(containsAny(fruits,["apple","grape"]));

console.log(containsAny(fruits,["apple","banana","pineapple"]));

console.log(containsAny(fruits,["grape", "pineapple"]));

回答by Justin Cuaresma

You could use lodashand do:

您可以使用lodash并执行以下操作:

_.intersection(originalTarget, arrayToCheck).length > 0

Set intersection is done on both collections producing an array of identical elements.

在两个集合上完成集合交集,生成相同元素的数组。

回答by Alexander

const areCommonElements = (arr1, arr2) => {
    const arr2Set = new Set(arr2);
    return arr1.some(el => arr2Set.has(el));
};

Or you can even have a better performance if you first find out which of these two arrays is longer and making Setout for the longest array, while applying somemethod on the shortest one:

或者,如果您首先找出这两个数组中的哪一个更长并Set找出最长的数组,同时some在最短的数组上应用方法,您甚至可以获得更好的性能:

const areCommonElements = (arr1, arr2) => {
    const [shortArr, longArr] = (arr1.length < arr2.length) ? [arr1, arr2] : [arr2, arr1];
    const longArrSet = new Set(longArr);
    return shortArr.some(el => longArrSet.has(el));
};

回答by kashpatel

I found this short and sweet syntax to match all or some elements between two arrays. For example

我发现这个简短而巧妙的语法可以匹配两个数组之间的所有或部分元素。例如

// OR operation. find if any of array2 elements exists in array1. This will return as soon as there is a first match as some method breaks when function returns TRUE

// 或操作。查找 array1 中是否存在任何 array2 元素。这将在第一次匹配时返回,因为当函数返回 TRUE 时某些方法会中断

let array1 = ['a', 'b', 'c', 'd', 'e'], array2 = ['a', 'b'];

console.log(array2.some(ele => array1.includes(ele)));

// prints TRUE

// 打印真

// AND operation. find if all of array2 elements exists in array1. This will return as soon as there is a no first match as some method breaks when function returns TRUE

// AND 运算。查找array1 中是否存在所有array2 元素。这将在没有第一个匹配项时返回,因为当函数返回 TRUE 时某些方法会中断

let array1 = ['a', 'b', 'c', 'd', 'e'], array2 = ['a', 'x'];

console.log(!array2.some(ele => !array1.includes(ele)));

// prints FALSE

// 打印错误

Hope that helps someone in future!

希望对未来的人有所帮助!