2013-12-17 34 views
3

要比較兩個List<String>並提取它們的差異,我使用Linq的Except使用Linq比較列表<String>與重複信息

即:

說我想使用LINQ爭取平等的以下兩個列表比較:

List1 = "0,1,2,2,3" 
List2 = "0,1,2,3" 

List<string> differences1 = List1.Except(List2).ToList(); 
List<string> differences2 = List2.Except(List1).ToList(); 

differences1differences2將沒有任何項目一樣,存在於兩個列表2,但兩者名單不是相等。我希望能夠提取列表之間的所有差異,其中包括重複的信息,其他信息不一樣。

提取兩個List<string>對象之間所有差異的最佳方法是什麼?

+0

您是否嘗試過使用鮮明的(),刪除重複和比較產生列表? – semao

+0

你應該真的包含相同的輸入/輸出。 – Servy

+0

編輯後我很困惑。你說你想要「0,1,2,2,3」和「0,1,2,3」是平等的,你想知道它們是不同的。咦? – Becuzz

回答

5

所以你要找什麼是Except上袋工作,而不是套。因此,如果一個序列有一個項目的兩個副本,並且您用一個副本減去一個集合,那麼應該留下一個副本,而不是像在Except那樣在執行減法之前將所有的序列減少爲不同的集合。

這使得它稍微不夠優雅,但它仍然不可怕。您只需要有一個將項目映射到副本數量的字典,而不是使用HashSet來表示其他集合中的項目。然後,對於每個項目,如果它在字典中,請從計數中刪除一個,並且不要放棄它,如果它不在字典中,則應該放棄。

public static IEnumerable<T> BagDifference<T>(IEnumerable<T> first 
    , IEnumerable<T> second) 
{ 
    var dictionary = second.GroupBy(x => x) 
     .ToDictionary(group => group.Key, group => group.Count()); 

    foreach (var item in first) 
    { 
     int count; 
     if (dictionary.TryGetValue(item, out count)) 
     { 
      if (count - 1 == 0) 
       dictionary.Remove(item); 
      else 
       dictionary[item] = count - 1; 
     } 
     else 
      yield return item; 
    } 
} 
+0

天才。這完全是我在找的東西。非常感謝你! – TestK

+0

@TestK你的問題還不是很清楚,你應該編輯它來澄清它。 – Servy

+0

編輯應該清除任何混淆。 – TestK

0

您可以通過該鍵組,然後使用除了比較組()

它應該是這樣的(未測試可能有錯別字):

var groupList1 = List1.GroupBy(x => x).ToList(); 
var groupList2 = List2.GroupBy(x => x).ToList(); 

var differences1 = groupList1.Except(groupList2).ToList(); 
var differences2 = groupList2.Except(groupList1).ToList(); 
0

你可以呼籲名單.Distinct()然後再比較它們:

List<string> differences1 = List1.Distinct().Except(List2).ToList(); 
List<string> differences2 = List2.Distinct().Except(List1).ToList(); 
+1

在使用'Except'之前調用'Distinct'毫無意義; '除外'本身將刪除重複。 – Servy

0

您可以使用Distinct消除重複項,然後進行比較。

var distinctList1 = List1.Distinct().ToList(); 
var distinctList2 = List2.Distinct().ToList(); 

var differences1 = distinctList1.Except(distinctList2).ToList(); 
var differences2 = distinctList2.Except(distinctList1).ToList(); 
+0

使用'Except'之前調用'Distinct'沒有意義; '除外'本身將刪除重複。 – Servy

0

您可以創建列表的副本,然後刪除其他所有存在:

var diff1 = list1.ToList(); 
var diff2 = list2.ToList(); 
diff1.RemoveAll(diff2.Remove); 
+0

1)這是突變兩個集合,而不是簡單地確定區別是什麼。 2)這將表現非常糟糕,因爲搜索並從列表中刪除項目並不便宜。 – Servy

+0

的確表現不佳!但這並不總是一個問題。雖然一個簡單的解決方案來獲得差異。 – erikH