C#의 두 객체 세트의 차이를 얻는 방법이 있습니까?
문제
C#에서 두 int 세트의 차이를 얻고 싶습니다. S1과 S2가 주어지면 S1이 아닌 S1에있는 int를 반환하고 싶습니다. 나는 다음과 같은 일을 할 수 있습니다.
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 구조물이 있는지 확실하지 않습니까? 고맙습니다.
해결책
나는 당신이 원한다고 생각합니다 해시 세트. 즉, 사용 목록을 사용하지 않고 해시 세트를 사용한 다음 작업을 사용할 수 있습니다. 어쨌든 당신이 대표하는 것이 실제로 '세트'라면 더 나은 유형입니다. (이미 목록이 있다면 '새로운 해시 세트'만 만들 수 있습니다.)
다른 팁
IEnumerable<T> a, b;
var added = a.Except(b);
var removed = b.Except(a);
List<int> s1 = new List<int>();
List<int> s2 = new List<int>();
return sl.FindAll( i => !s2.Contains(i) )
from x in s1 where ! s2.contains(x) select x
다음은 두 개의 ienumerable 사이에 정렬되지 않은 차이를 찾아야 할 때 편리 할 수있는 두 가지 확장 방법입니다 (Leppie Wrapper가 제공 한 답변과 연장 메소드에 대한 답과 다소 동일합니다).
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();
}
}
또 다른 유용한 API는 대칭 차이를 얻습니다.
제휴하지 않습니다 StackOverflow