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

例如:

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

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

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

如何在JavaScript中实现?


当前回答

香草JS

2016年:

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

ES6:

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

它的工作原理

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

其他回答

使用筛选器/indexOf:

函数containsAny(源,目标){var result=source.filter(函数(项){return target.indexOf(项)>-1});返回(result.length>0);} //结果var fruits=[“苹果”、“香蕉”、“橙色”];console.log(包含任何(水果,[“苹果”,“葡萄”]);console.log(包含任何(水果,[“苹果”,“香蕉”,“菠萝”]);console.log(包含任何(水果,[“葡萄”,“菠萝”]);

如果不需要类型强制(因为使用了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);

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

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

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


更新:

以下是我如何将其组织成一个函数(与之前的一些小变化):

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

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

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


更新2:

虽然我上面的解决方案可能有效,并且(希望更)可读,但我认为处理我描述的概念的“更好”方法是做一些稍微不同的事情。上述解决方案的“问题”是,循环中的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;
};

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

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

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

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

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

香草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;
    });
};

正如@loganofsmyth所指出的,您可以在ES2016中将其缩短为

/**
 * @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.
 */
const findOne = (haystack, arr) => {
    return arr.some(v => haystack.includes(v));
};

或者简单地称为arr.some(v=>haystalk.includes(v));

如果要确定数组是否包含其他数组中的所有项,请将some()替换为every()或作为arr.every(v=>haystalk.includes(v));

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

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

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