2009-04-30 4 views
15

Ben C# içinde iki set arasındaki farkı elde etmek istiyorum. S1 ve s2 verildiğinde, s2 cinsinden olan ve s2 cinsinden olmayan bu mürekkepleri iade etmek istiyorum.C# içinde iki nesne arasında fark elde etmek için bir yolu var # C#

Böyle bir şey yapabilirim, ama birilerinin temiz bir şey gösterip gösteremeyeceğini merak ediyordum. Ben

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

değil varolan yöntem veya LINQ herkes işaret etmek mümkün olabileceğini inşa varsa emin gibi bir şey yapmak istersiniz? Teşekkür ederim.

cevap

18

Bence HashSet.Except. Yani, kullanım listelerinden ziyade HashSets'i kullanın ve ardından işlem kullanılabilir. Temsil ettiğiniz şey zaten bir 'set' ise, bu daha iyi bir tiptir. (Zaten bir listesi varsa, sadece bunun dışında 'yeni HashSet' oluşturabilir.)

+0

harika teşekkür ederiz. Except(), aradığım yöntemdir ve HashSets konusunda tavsiyenizi alırım. – SiC

+0

Bunun dışında bir genişletme işlevi var, değil mi? – leppie

+0

Tüm IEnumerables için bir Enumerable.Except uzantısı yöntemi vardır. Ancak HashSet'in HashSets için özel olarak bir yöntemi vardır. – 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

Bunun, Enumerable.Except'i kullandığını unutmayın, bu yüzden System.Linq'i kullanmanız gerekir. http://msdn.microsoft.com/en-us/library/bb300779.aspx – Brian

+0

Bu bir problem mi? :) – leppie

+1

Sorun? Hayır, sadece bu kodu kesip yapıştırabilecek ve derlemeyi bulamayan birisine yardım etmek istedim. – Brian

0

Burada sırasız bulmak için gerektiğinde kullanışlı gelebilir iki uzatma yöntemleri iki IEnumerable arasındaki farklar (leppie sarmalayıcı tarafından uzatma yöntemlerine verilen cevap ile aynı veya daha azdır):

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