检查一个数组是否包含 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
Check if an array contains any element of another array in JavaScript
提问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(..) >= 0
and 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 arr
contains the target items. At the end, found
will 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 true
because the second array's 3
exists 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 targetArray
be 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 indexOf
inside 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
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
回答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 Set
out for the longest array, while applying some
method 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!
希望对未来的人有所帮助!