2009-04-30 29 views
15

Tôi muốn có sự khác biệt giữa hai bộ int trong C#. Cho s1 và s2 tôi muốn trả về các int đó nằm trong s1 và không ở s2. Tôi có thể làm một việc gì đó như:Có cách nào để có được sự khác biệt giữa hai bộ đối tượng trong C#

List<int> s1 = new List<int>(); 
    List<int> s2 = new List<int>(); 

    foreach (int i in s1) 
    { 
     if (s1.Contains(i)) 
     { 
      // 
     } 
     else 
     { 
      // 
     } 
    } 

Nhưng tôi đã tự hỏi liệu có ai có thể chỉ ra điều gì sạch hơn không. Tôi muốn làm một cái gì đó như

List<int> omitted = s1.Difference(s2); 

Không chắc chắn nếu có phương pháp hiện có hoặc cấu trúc LINQ mà bất kỳ ai cũng có thể chỉ ra? Cảm ơn bạn.

Trả lời

18

Tôi nghĩ bạn muốn HashSet.Except. Đó là, thay vì sử dụng Danh sách, sử dụng HashSets, và sau đó hoạt động có sẵn. Đây là một loại tốt hơn nếu những gì bạn đang đại diện thực sự là một 'bộ' anyway. (Nếu bạn đã có một danh sách, bạn chỉ có thể tạo ra một 'HashSet mới' ra khỏi nó.)

+0

thankyou tuyệt vời. Ngoại trừ() là phương pháp tôi đang tìm kiếm và tôi đưa ra lời khuyên của bạn về HashSets. – SiC

+0

Ngoại trừ chức năng mở rộng, phải không? – leppie

+0

Có một phương pháp mở rộng Enumerable.Except cho tất cả IEnumerables. Nhưng HashSet có một phương thức Ngoại trừ đặc biệt cho HashSets. – Brian

1
 
from x in s1 
where ! s2.contains(x) 
select x 
2
List<int> s1 = new List<int>(); 
List<int> s2 = new List<int>(); 

return sl.FindAll(i => !s2.Contains(i)) 
20
IEnumerable<T> a, b; 

var added = a.Except(b); 
var removed = b.Except(a); 
+1

Lưu ý rằng điều này sử dụng Enumerable.Except, vì vậy bạn cần sử dụng System.Linq. http://msdn.microsoft.com/en-us/library/bb300779.aspx – Brian

+0

Đó có phải là sự cố không? :) – leppie

+1

Sự cố? Không, tôi chỉ muốn giúp ai đó có thể cắt và dán mã này và thấy rằng nó không biên dịch. – Brian

0

Dưới đây là hai phương pháp khuyến nông có thể đến tiện dụng khi bạn cần phải tìm thứ tự sự khác biệt giữa hai IEnumerable (nó nhiều hơn hoặc ít hơn giống như câu trả lời được đưa ra bởi leppie wrapper vào các phương pháp mở rộng):

public class EnumerableDifferences<T> 
{ 
    public IEnumerable<T> Added { get; } 
    public IEnumerable<T> Removed { get; } 

    public EnumerableDifferences(IEnumerable<T> added, IEnumerable<T> removed) 
    { 
     Added = added; 
     Removed = removed; 
    } 
} 

public static class EnumerableExtensions 
{ 
    public static HashSet<TSource> ToHashSet<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer) 
    { 
     return new HashSet<TSource>(source, comparer); 
    } 

    public static IEnumerable<TSource> ExceptBy<TSource, TKey>(this IEnumerable<TSource> first, IEnumerable<TSource> second, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> keyComparer = null) 
    { 
     return first 
      .ExceptBy(keySelector, second.Select(keySelector), keyComparer); 
    } 

    public static IEnumerable<TSource> ExceptBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEnumerable<TKey> keys, IEqualityComparer<TKey> keyComparer = null) 
    { 
     var secondKeys = keys.ToHashSet(keyComparer); 

     foreach (var firstItem in source) 
     { 
      var firstItemKey = keySelector(firstItem); 

      if (!secondKeys.Contains(firstItemKey)) 
      { 
       yield return firstItem; 
      } 
     } 
    } 

    public static EnumerableDifferences<TSource> DifferencesBy<TSource, TKey>(this IEnumerable<TSource> first, IEnumerable<TSource> second, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> keyComparer = null) 
    { 
     keyComparer = keyComparer ?? EqualityComparer<TKey>.Default; 

     var removed = first.ExceptBy(second, keySelector, keyComparer); 
     var added = second.ExceptBy(first, keySelector, keyComparer); 

     var result = new EnumerableDifferences<TSource>(added, removed); 

     return result; 
    } 

    public static EnumerableDifferences<TSource> Differences<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer = null) 
    { 
     return first 
      .DifferencesBy(second, x => x, comparer); 
    } 
} 

public static class Program 
{ 
    public static void Main(params string[] args) 
    { 
     var l1 = new[] { 'a', 'b', 'c' }; 
     var l2 = new[] { 'a', 'd', 'c' }; 

     var result = l1.Differences(l2); 

     Console.ReadKey(); 
    } 
} 
Các vấn đề liên quan