2009-04-30 2 views
15

C#에서 두 개의 int 집합 사이의 차이점을 얻고 싶습니다. s1과 s2가 주어지면 s1에 있고 s2에없는 int를 반환하고 싶습니다. 나는 다음과 같은 것을 할 수있다 :C#에서 두 세트의 개체 사이의 차이점을 얻을 수있는 방법이 있나요?

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

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

그러나 나는 누군가가 더 깨끗한 것을 지적 할 수 있는지 궁금했다. 나는

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

하지 기존의 방법 또는 LINQ는 누구나 지적 할 수있을 것으로 구성이 확실와 같은 일을하기를 원하십니까? 고맙습니다.

답변

18

나는 당신이 원하는 것이라고 생각한다. HashSet.Except. 즉, List를 사용하는 대신 HashSet을 사용하면 작업을 사용할 수 있습니다. 당신이 표현하는 것이 실제로 '집합'이라면 이것은 더 나은 유형입니다. (이미 목록이있는 경우, 당신은 단지 그것에서 '새로운 HashSet의'를 만들 수 있습니다.)

+0

awesome thankyou. Except() 메서드는 내가 찾고있는 메서드이며 HashSet에 대한 조언을 구합니다. – SiC

+0

확장 기능은 제외하고는 안됩니까? – leppie

+0

모든 IEnumerables에 대해 Enumerable.Except 확장 메서드가 있습니다. 그러나 HashSet에는 HashSet을위한 특별히 예외적 인 메소드가 있습니다. – 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

Enumerable.Except를 사용하므로 System.Linq를 사용해야합니다. http://msdn.microsoft.com/en-us/library/bb300779.aspx – Brian

+0

문제가 있습니까? :) – leppie

+1

문제가 있습니까? 아니요,이 코드를 잘라내어 붙여 넣을 수있는 사용자를 도와서 컴파일하지 않는 것을 찾았습니다. – Brian

0

가 여기에 정렬되지 않은 찾을 필요가있을 때 유용 올 수있는 2 개 개의 확장 방법이 있습니다 두 IEnumerable 사이의 차이점 (확장 메소드에 leppie 래퍼가 제공 한 대답과 거의 같음) :

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(); 
    } 
} 
관련 문제