假设我有两个集合:
c1 - [{a:1},{a:2},{a:3}]
和
c2 - [{a:1},{a:7},{a:8}]
使用Underscore.JS
,将c2
中的唯一项快速添加到c1
中的最快方法是什么?集合中的实际数字分别为2K
和500
,操作频繁进行,因此必须具有高性能!
更新1 - 我只使用Underscore.JS
几天,我找不到一种将一个集合添加到另一个集合中的方法(我可以自己筛选c2
)- 在Underscore.JS
中是否很简单?
假设我有两个集合:
c1 - [{a:1},{a:2},{a:3}]
和
c2 - [{a:1},{a:7},{a:8}]
使用Underscore.JS
,将c2
中的唯一项快速添加到c1
中的最快方法是什么?集合中的实际数字分别为2K
和500
,操作频繁进行,因此必须具有高性能!
更新1 - 我只使用Underscore.JS
几天,我找不到一种将一个集合添加到另一个集合中的方法(我可以自己筛选c2
)- 在Underscore.JS
中是否很简单?
尝试:
_.uniq(_.union(c1, c2), false, _.property('a'))
详细内容如下:
_.union(*arrays)
计算传入数组的并集。
_.property(key)
(自版本1.6.0起)
返回一个函数,该函数将返回任何传入对象的键属性。
_.uniq(array, [isSorted], [iteratee])
使用
===
测试对象相等性,生成一个无重复项的数组副本。如果您事先知道数组已排序,则传递true
以进行更快的算法运行。如果要基于转换计算唯一项,请传递迭代器函数。
uniq()
函数的文档提到,如果列表已排序,则函数运行速度会更快。此外,使用链式调用可以提高可读性。因此,您可以这样做:
_.chain(c1).union(c2).sortBy("a").uniq(true, function(item){ return item.a; }).value();
_.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()
由于两个对象中都有大量的属性,并且此算法经常运行,因此最好使用核心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来测试它。
a
的值进行排序? - AlexStack