2012-11-22 27 views
25

兩個集合提供的,我有兩個類別:合併使用Underscore.JS

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

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

什麼是從c2添加獨特的物品到的最快方法c1使用Underscore.JS?收藏中的實際數字爲2K(對於c1500對於c2),操作經常執行,因此必須表現高性能!

更新1 - 我只使用Underscore.JS幾天,我無法找到一個方法來添加一個集合到另一個(我可以過濾c2我自己) - 是瑣碎Underscore.JS

+0

是兩個數組中的元素是否基於'a'的值排序? – AlexStack

+0

@AlexStack不幸的是,但我明白你來自哪裏。 – user1514042

回答

44

下面的意志:

  • 創建一個包含C1和C2的所有元素的數組。見union
  • 從該混合中創建一個僅包含唯一元素的新數組。見uniq

請注意,只有當您的所有對象都具有屬性a時,這才起作用。

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

你可以在this question找到其他的選擇。

+0

謝謝,明白了。 – user1514042

+1

對,如果沒有將該回調傳遞給uniq,將使用===比較對象。 ({a:1} === {a:1}將爲false)。 – Matias

+0

聲音,我只是忽略了'return item.a;',這正是我需要的。 – user1514042

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]); 
     } 
    } 
} 

這裏是a JSfiddle to test it

+0

@Rob W我希望得到理想的單線解決方案... – user1514042

4

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()

9

嘗試:

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

詳細地:

  1. _.union(*arrays)

    計算傳入的陣列的結合。

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

    返回將自身返回任何傳入的對象的關鍵屬性的功能。

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

    可生產陣列的無重複的版本,使用===測試對象的相等。如果事先知道該數組已排序,則爲isSorted傳遞true將運行更快的算法。如果你想基於轉換來計算唯一的項目,傳遞一個迭代函數。