使用Underscore.JS合并两个集合

32

假设我有两个集合:

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

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

使用Underscore.JS,将c2中的唯一项快速添加到c1中的最快方法是什么?集合中的实际数字分别为2K500,操作频繁进行,因此必须具有高性能!

更新1 - 我只使用Underscore.JS几天,我找不到一种将一个集合添加到另一个集合中的方法(我可以自己筛选c2)- 在Underscore.JS中是否很简单?


这两个数组的元素是否根据a的值进行排序? - AlexStack
很遗憾,@AlexStack,我不行,但我理解你的想法。 - user1514042
4个回答

53
以下将:
  • 创建一个包含 c1 和 c2 所有元素的新数组。参见 union
  • 从混合的数组中创建一个仅包含唯一元素的新数组。参见 uniq

请注意,只有当你所有的对象都具有属性 a 时,这将起作用。

_.uniq(_.union(c1, c2), false, function(item, key, a){ return item.a; });

您可以在这个问题中找到其他选项。


1
正确的做法是将回调函数传递给uniq,否则对象将使用 === 进行比较。({a:1} === {a:1} 将返回 false)。 - mati
声音,我刚刚忽略了'return item.a;',这正是我需要的。 - user1514042

16

尝试:

_.uniq(_.union(c1, c2), false, _.property('a'))

详细内容如下:

  1. _.union(*arrays)

    计算传入数组的并集。

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

    返回一个函数,该函数将返回任何传入对象的键属性。

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

    使用 === 测试对象相等性,生成一个无重复项的数组副本。如果您事先知道数组已排序,则传递 true 以进行更快的算法运行。如果要基于转换计算唯一项,请传递迭代器函数。


6
< p > uniq() 函数的文档提到,如果列表已排序,则函数运行速度会更快。此外,使用链式调用可以提高可读性。因此,您可以这样做:

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

或者,如果您更喜欢未加锁的版本(比可读性差11个字符):
_.uniq(_.sortBy(_.union(c1,c2),"a"),true, function(item){ return item.a; });

uniq()函数的文档和示例并没有清楚地说明回调函数的工作原理。在uniq()函数的算法中,该函数会对来自两个列表的每个元素都调用这个函数。如果这个函数的结果相同,则删除该元素(假设它是重复的)。

实际上,union()在对数组进行操作时就能防止重复项的出现。我们可以利用这个特点:

_.map(_.union(_.pluck(c1,"a"),_.pluck(c2,"a")),function (item) {return {a:item};});

上面的代码首先将对象列表转换为简单数组(pluck()),然后使用union()将它们组合起来,最后使用map()生成对象列表。

参考资料:uniq()


1

由于两个对象中都有大量的属性,并且此算法经常运行,因此最好使用核心JavaScript而不是任何库:

//adds all new properties from the src to dst. If the property already exists, updates the number in dst. dst and src are objects
function extendNumberSet( dst, src ) {
    var allVals = [];
    for ( var i = 0; i < dst.length; i++ ) {
        allVals.push(dst[i].a);
    }
    for ( var i = 0; i < src.length; i++ ) {
        if ( allVals.indexOf( src[i].a ) === -1 ) {
            dst.push( src[i] );
        }
    }
}

这里有一个JSfiddle来测试它


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