Javascript 使用 Underscore.JS 合并两个集合
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13514121/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Merging two collections using Underscore.JS
提问by user1514042
Provided I have two collections:
如果我有两个集合:
c1 - [{a:1},{a:2},{a:3}]
c1 - [{a:1},{a:2},{a:3}]
and
和
c2 - [{a:1},{a:7},{a:8}]
c2 - [{a:1},{a:7},{a:8}]
what's the fastest way to add unique items from c2into c1using Underscore.JS? The real numbers in collections would be 2Kfor c1and 500for c2, the operation is performed often, so must be performant!
什么是添加从独特的项目以最快的方式c2进入c1使用Underscore.JS?集合中的实数是2Kforc1和500for c2,操作经常执行,所以必须是高性能的!
Update 1- I'm only using Underscore.JSfor a few days, I couldn't find a way to add one collection into another (I can filter c2myself) - is that trivial in Underscore.JS?
更新 1- 我只使用Underscore.JS了几天,我找不到将一个集合添加到另一个集合中的方法(我可以c2自己过滤)- 这很简单Underscore.JS吗?
回答by Matias
The following will:
以下将:
- create a new array that contains all the elements of c1 and c2. See union.
- from that mix, create a new array that contains only the unique elements. See uniq.
Note that this would work only if all your objects have the property a.
请注意,这仅在您的所有对象都具有属性时才有效a。
_.uniq(_.union(c1, c2), false, function(item, key, a){ return item.a; });
You can find other options in this question.
您可以在此问题中找到其他选项。
回答by HaNdTriX
Try:
尝试:
_.uniq(_.union(c1, c2), false, _.property('a'))
In detail:
详细:
_.union(*arrays)Computes the union of the passed-in arrays.
_.property(key)(since Version 1.6.0)Returns a function that will itself return the key property of any passed-in object.
_.uniq(array, [isSorted], [iteratee])Produces a duplicate-free version of the array, using
===to test object equality. If you know in advance that the array is sorted, passingtruefor isSorted will run a much faster algorithm. If you want to compute unique items based on a transformation, pass an iteratee function.
_.union(*arrays)计算传入数组的并集。
_.property(key)(从 1.6.0 版开始)返回一个函数,该函数本身将返回任何传入对象的键属性。
_.uniq(array, [isSorted], [iteratee])生成数组的无重复版本,
===用于测试对象相等性。如果您事先知道数组已排序,则传递trueisSorted 将运行更快的算法。如果要根据转换计算唯一项,请传递 iteratee 函数。
回答by AlexStack
The documentation for uniq()function mentions that it runs much faster if the list is sorted. Also using the chained calls can improve readability. So you can do:
uniq()函数的文档提到,如果对列表进行排序,它的运行速度会快得多。使用链式调用也可以提高可读性。所以你可以这样做:
_.chain(c1).union(c2).sortBy("a").uniq(true, function(item){ return item.a; }).value();
Or if you prefer the unchained version (which is 11 characters shorter but less readable):
或者,如果您更喜欢未链接的版本(短 11 个字符但可读性较差):
_.uniq(_.sortBy(_.union(c1,c2),"a"),true, function(item){ return item.a; });
The documentation and examples for uniq()don't make it clear how the callback function works. The algorithm for uniq()function calls this function on every element from both lists. If the result of this function is the same, it removes that element (assuming it is duplicated).
的文档和示例uniq()没有说明回调函数是如何工作的。uniq()函数的算法在两个列表中的每个元素上调用此函数。如果此函数的结果相同,则删除该元素(假设它是重复的)。
union()in fact prevents duplicates when called on an array. We can use this fact too:
union()事实上,在数组上调用时可以防止重复。我们也可以使用这个事实:
_.map(_.union(_.pluck(c1,"a"),_.pluck(c2,"a")),function (item) {return {a:item};});
The above like first converts the list of objects to simple arrays (pluck()) then combines them using union()and eventually uses map()to make a list of objects.
上面的like首先将对象列表转换为简单的数组(pluck()),然后使用将它们组合起来union(),最终使用map()来制作一个对象列表。
Reference: uniq()
参考:uniq()
回答by AlexStack
Since there is a huge number of properties in both objects and this algorithm runs often, it would be better to use core Javascript instead of any library:
由于两个对象中都有大量的属性,而且这个算法经常运行,所以最好使用核心 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] );
}
}
}
here is a JSfiddle to test it.

