2013-05-10 59 views
1

我需要在Union上的一個實現來比較對象的屬性,而不是對象本身。我想出了以下情況:UnionBy Linq執行

public static IEnumerable<TSource> UnionBy<TSource, TKey>(
    this IEnumerable<TSource> first, 
    IEnumerable<TSource> second, 
    Func<TSource, TKey> keySelector, 
    IEqualityComparer<TKey> keyComparer = null) 
{ 
    HashSet<TKey> keys = new HashSet<TKey>(keyComparer); 
    foreach (TSource element in first) 
    { 
     if (keys.Add(keySelector(element))) 
     { 
      yield return element; 
     } 
    } 
    foreach (TSource element in second) 
    { 
     if (!keys.Add(keySelector(element))) 
     { 
      continue; 
     } 
     yield return element; 
    } 
} 

,我可以說的線沿線的一些使用方法:

result = first.UnionBy(second, x => x.Property1); 

這對我的作品,但我想知道,如果沒有一些已經實施在Linq,我失蹤(除了執行我自己的EqualityComparer這對我來說似乎不那麼直觀)。

因爲我不會使用相同的屬性我想這個聯盟每次我要麼必須進行多次EqualityComparer的每個這似乎不正確的給我,或者做一些通用的EqualityComparer,將採取情況在屬性選擇器Func中。對我來說,看起來不那麼直觀,只是提供了接受屬性選擇器本身的通用Linq擴展。

+1

'Union'具有[過載(http://msdn.microsoft.com/en-us/library/bb358407.aspx)與自定義'IEqualityComparer '或者只是在你的類中實現'Equals'和'GetHashCode'。 – 2013-05-10 13:15:02

+0

@TimSchmelter「除了實現我自己的'EqualityComparer',這對我來說似乎不那麼直觀。」我更新了這個問題,並解釋了爲什麼我選擇不這樣做。基本上,我創建單獨的「EqualityComparer」或忽略「Equals」而不想在聯盟之外使用它們是不符合直覺的。 – NominSim 2013-05-10 13:23:56

+1

沒有這樣的方法已經實施,你自己聽三種可能的解決方案。我更喜歡通用的'EqualityComparer',因爲你必須實現它一次,並可以使用它的許多方法(如'聯合','區別','等'等等) – sloth 2013-05-10 13:29:04

回答

2

是可以作爲代替如下寫:

var q = first.Concat(second).GroupBy(x => x.Property1).Select(x => x.First()); 
+0

這看起來不錯,只是我正在尋找。謝謝。 – NominSim 2013-05-10 13:48:54