使用Underscore.JS合并两个集合

use*_*042 28 javascript underscore.js

如果我有两个集合:

c1 - [{a:1},{a:2},{a:3}]

c2 - [{a:1},{a:7},{a:8}]

什么是添加从独特的项目以最快的方式c2进入c1使用Underscore.JS?集合中的实数将为2Kfor c1500for c2,操作经常执行,因此必须具有高性能!

更新1 - 我只使用Underscore.JS了几天,我找不到将一个集合添加到另一个集合中的方法(我可以过滤c2自己) - 这是微不足道的Underscore.JS吗?

Mat*_*ias 52

以下将:

  • 创建一个包含c1和c2所有元素的新数组.见工会.
  • 从该混合中,创建一个仅包含唯一元素的新数组.见uniq.

请注意,只有当所有对象都具有该属性时,这才有效a.

_.uniq(_.union(c1, c2), false, function(item, key, a){ return item.a; });
Run Code Online (Sandbox Code Playgroud)

您可以在此问题中找到其他选项.

  • 查看_.union的源代码,它已经调用了uniq(). (4认同)

HaN*_*riX 15

尝试:

_.uniq(_.union(c1, c2), false, _.property('a'))
Run Code Online (Sandbox Code Playgroud)

详细地:

  1. _.union(*arrays)

    计算传入数组的并集.

  2. _.property(key) (自1.6.0版本起)

    返回一个函数,该函数本身将返回任何传入对象的key属性.

  3. _.uniq(array, [isSorted], [iteratee])

    生成数组的无副本版本,===用于测试对象相等性.如果您事先知道数组已排序,则传递trueisSorted将运行更快的算法.如果要基于转换计算唯一项,请传递iteratee函数.


Ale*_*ack 6

uniq()函数文档提到如果列表已排序,它运行得更快.同样使用链式调用可以提高可读性.所以你可以这样做:

_.chain(c1).union(c2).sortBy("a").uniq(true, function(item){ return item.a; }).value();
Run Code Online (Sandbox Code Playgroud)

或者,如果您更喜欢未链接的版本(缩写为11个字符,但可读性较差):

_.uniq(_.sortBy(_.union(c1,c2),"a"),true, function(item){ return item.a; });
Run Code Online (Sandbox Code Playgroud)

文档和示例uniq()没有说明回调函数的工作原理.uniq()函数的算法在两个列表的每个元素上调用此函数.如果此函数的结果相同,则删除该元素(假设它是重复的).

union()事实上,在数组上调用时可以防止重复.我们也可以使用这个事实:

_.map(_.union(_.pluck(c1,"a"),_.pluck(c2,"a")),function (item) {return {a:item};});
Run Code Online (Sandbox Code Playgroud)

上面首先将对象列表转换为简单数组(pluck())然后将它们组合使用union(),最终用于map()制作对象列表.

参考:uniq()