2010-03-08 90 views
16

我有這樣的兩名成員名單:的LINQ找到差異,兩個列表

前:彼得,肯,朱莉婭,湯姆

後:彼得·羅伯特,朱莉婭,湯姆

正如你可以看到,肯是和羅伯特是在。

我想要的是檢測到的變化。我想要列出兩個列表中發生了什麼變化。 linq如何幫助我?

+2

我認爲你需要定義「變」多一點。例如,是否改變了項目的順序「改變」給你? –

回答

27

您的問題沒有完全指定,但我假設您正在尋找作爲集合的差異(即排序無關緊要)。如果是這樣,你想要兩個集合中的symmetric difference。您可以使用Enumerable.Except實現這一目標:

before.Except(after).Union(after.Except(before)); 
+0

@威爾:感謝您的更正。 – jason

5

另一種方式:

before.Union(after).Except(before.Intersect(after)) 
20

作爲替代LINQ答案,這必須通過這兩個列表兩次,使用HashSet.SymmetricExceptWith()

var difference = new HashSet(before); 
difference.SymmetricExceptWith(after); 

莫非效率要高得多。

2

這裏是有版本O(n)的複雜性,提供您的序列都下令:

public static IEnumerable<T> SymmetricDifference<T>(IEnumerable<T> coll1, IEnumerable<T> coll2, IComparer<T> cmp) 
    { 
     using (IEnumerator<T> enum1 = coll1.GetEnumerator()) 
     using (IEnumerator<T> enum2 = coll2.GetEnumerator()) 
     { 
      bool enum1valid = enum1.MoveNext(); 
      bool enum2valid = enum2.MoveNext(); 
      while (enum1valid && enum2valid) 
      { 
       int cmpResult = cmp.Compare(enum1.Current, enum2.Current); 
       if (cmpResult < 0) 
       { 
        yield return enum1.Current; 
        enum1valid = enum1.MoveNext(); 
       } 
       else if (cmpResult > 0) 
       { 
        yield return enum2.Current; 
        enum2valid = enum2.MoveNext(); 
       } 
       else 
       { 
        enum1valid = enum1.MoveNext(); 
        enum2valid = enum2.MoveNext(); 
       } 
      } 
      while (enum1valid) 
      { 
       yield return enum1.Current; 
       enum1valid = enum1.MoveNext(); 
      } 
      while (enum2valid) 
      { 
       yield return enum2.Current; 
       enum2valid = enum2.MoveNext(); 
      } 
     } 
    } 


    public static IEnumerable<T> SymmetricDifference<T>(IEnumerable<T> coll1, IEnumerable<T> coll2) 
    { 
     return SymmetricDifference(coll1, coll2, Comparer<T>.Default); 
    } 
+1

這隻適用於排序的序列,對吧?對於任意序列,不能只爲O(n)產生symdiff。 – Vlad

+0

確實如此,只需看一下聯合迭代。它是從合併排序順序合併的稍微修改版本。雖然它對於未排序的函數不起作用,但對於排序來說它是非常有效的,所以在許多情況下,對集合進行預先排序然後使用此篩選器將更快且更易於使用內存 - > n + 2 *(n log n)而不是一些naiive所有對所有n^2或一些哈希表內存豬......當然_many_元素當然:) – quetzalcoatl

相關問題