【发布时间】:2015-04-02 15:13:52
【问题描述】:
我想知道两个或多个数组是否有共同的项目,但我不在乎这些项目是什么。我知道 lodash 有一个 _.intersection 方法,但我不需要它来遍历每个数组的每一项。相反,我需要类似_.hasIntersection 的方法,一旦发现第一个常见的事件,它就会停止在数组中查找。 lodash 有这样的东西吗?
【问题讨论】:
标签: javascript arrays lodash
我想知道两个或多个数组是否有共同的项目,但我不在乎这些项目是什么。我知道 lodash 有一个 _.intersection 方法,但我不需要它来遍历每个数组的每一项。相反,我需要类似_.hasIntersection 的方法,一旦发现第一个常见的事件,它就会停止在数组中查找。 lodash 有这样的东西吗?
【问题讨论】:
标签: javascript arrays lodash
这种方法可以让您在任意数量的数组中高效地搜索交集。
function hasIntersection() {
var collections = _.rest(arguments);
return _.some(_.first(arguments), function(item) {
return _(collections)
.chain()
.map(_.ary(_.partial(_.includes, item), 1))
.compact()
.size()
.isEqual(collections.length)
.value();
});
}
hasIntersection() 函数从创建collections 开始,这些是我们要在其中查找相交值的集合,减去第一个。它返回some() 的值,它使用first() 数组参数进行迭代,some() 的回调比较传递给函数的所有其他数组。
这是通过包装 collections 并构建调用链来完成的。它使用chain() 来启用显式链接,因为我们希望在链的末尾将isEqual() 链接到size()。
我们将collections 变量(一个数组数组)映射到includes() 函数。这会产生一个布尔值数组,真正的意思是其中一个集合中有一个相交的值。下一步是使用compact() 删除虚假值。我们剩下的是相交集合的数量。
如果相交集合的数量与collections 的长度相同,则我们找到了一个与所有集合相交的值,并且可以退出。这种方法很有效,因为some() 和includes() 存在短路
hasIntersection([ 1, 2 ], [ 2, 3 ]);
// → true
hasIntersection([ 1, 2, 3 ], [ 2, 4, 5 ], [ 2 ]);
// → true
hasIntersection([ 1, 2 ], [ 3, 4 ], [ 5, 6 ], [ 7, 8 ]);
// → false
【讨论】:
_.rest 需要一个函数。这是 lodash 的重大变化吗?