检查一个数组是否包含在另一个数组中。

7

I have

['a', 'b', 'c']

我想知道这个数组是否包含在另一个数组中:
['a', 'b', 'c', 'd']

我知道可以使用两个循环,逐项检查,但是有没有一行代码可以实现呢?


你的意思是想知道数组1的值是否都在数组2中吗?还是整个数组(包括[])都在其中? - Alan
也许可以参考https://dev59.com/6HI-5IYBdhLWcg3wsKr9 - Bradley Thomas
https://dev59.com/TWoy5IYBdhLWcg3wUcf_ - Eyal Ofri
2
如果数组元素像你的示例一样是简单字符串,那么你可以执行 contains = (y.sort().join('').indexOf(x.sort().join('')) !== -1); - 这里 x 是较小的数组(必需的),而 y 是较大的数组(干草堆)。 - techfoobar
@Alan 是的,只有真或假,但仅当整个 needle 能够在 haystack 中找到时。 - doniyor
显示剩余3条评论
2个回答

14
你可以使用Array.prototype.some来实现这个任务。它会将提供的函数应用于数组中的每个元素,并返回true,如果其中任何一个元素满足该函数的条件。以下代码将在array中任意元素不包含在otherArray中时返回true,你可以使用它来确定一个数组是否完全包含另一个数组:
return !array.some(function(item) {
   return otherArray.indexOf(item) === -1;
});

然而,这不是最优雅的解决方案。该逻辑可以总结为:

数组中没有任何项不在另一个数组中

这个表述有太多的否定词。我们可以使用Array.prototype.every代替,这个方法非常类似于之前的方法,不同之处在于它仅在数组中的所有项都对提供的函数返回true时才返回true。下面是相当于之前的代码:

return array.every(function(item) {
   return otherArray.indexOf(item) !== -1;
});

除此之外,可以概括为:

一个数组中的所有元素都在另一个数组中

最后,我们可以将其实现为一种附加的原型函数。请注意,every的第二个参数是可选的,并在提供时设置函数中this的引用。如果我们没有传递它,我们将无法引用外部范围的this

Array.prototype.contains = function(array) {
    return array.every(function(item) {
        return this.indexOf(item) !== -1;
    }, this);
}

现在我们可以将这个代码作为一行代码在我们的代码中使用:

['a', 'b', 'c'].contains(['a', 'b']) // returns true

如果您能够使用ECMAScript 6,您可以使用箭头函数将其变为真正的一行代码。

return array.every(item => otherArray.indexOf(item) !== -1);

1
Array.prototype.someArray.prototype.every 是 ECMAScript 5 的一部分,在大多数现代浏览器中都得到了支持,包括移动浏览器。值得注意的是,它不受 IE8 或更早版本的支持。http://caniuse.com/#feat=es5 - Robin James Kerrison

7

ES6单行代码简述

containedArray.every(element => mainArray.includes(element))

在ES6 @James Brierley的建议之上,可以使用every(...)(如果所有元素都通过我们提供的测试,则返回true - 否则返回false),以及includes。我认为后者更易读,并且比检查index !== -1更不容易出错。
var mainArray = [1, 30, 39, 29, 10, 13];

var containedArray = [1, 30, 39, 29]

console.log(containedArray.every(element => mainArray.includes(element)));

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