有没有办法在c#中获取两组对象之间的差异
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/806152/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a way to get the difference between two sets of objects in c#
提问by SiC
I want to get the difference between two sets of ints in c#. Given s1 and s2 I want to return those ints which are in s1 and not in s2. I can do something such as:
我想在 C# 中获得两组整数之间的差异。鉴于 s1 和 s2,我想返回那些在 s1 而不是在 s2 中的整数。我可以做一些事情,例如:
List<int> s1 = new List<int>();
List<int> s2 = new List<int>();
foreach (int i in s1)
{
if (s1.Contains(i))
{
//
}
else
{
//
}
}
But I was wondering if anyone can point out anything cleaner. I would like to do something such as
但我想知道是否有人可以指出任何更清洁的东西。我想做一些诸如
List<int> omitted = s1.Difference(s2);
Not sure if there is an existing method or a LINQ construct that anyone might be able to point out? Thank you.
不确定是否存在任何人都可以指出的现有方法或 LINQ 构造?谢谢你。
采纳答案by Brian
I think you want HashSet.Except. That is, rather than use Lists, use HashSets, and then the operation is available. This is a better type if what you are representing is really a 'set' anyway. (If you already have a list, you can just create a 'new HashSet' out of it.)
我想你想要HashSet.Except。也就是不使用Lists,使用HashSets,然后操作就可以了。如果您所代表的内容确实是一个“集合”,那么这是一种更好的类型。(如果您已经有一个列表,您可以从中创建一个“新的 HashSet”。)
回答by IMil
from x in s1 where ! s2.contains(x) select x
回答by Chad Grant
List<int> s1 = new List<int>();
List<int> s2 = new List<int>();
return sl.FindAll( i => !s2.Contains(i) )
回答by leppie
IEnumerable<T> a, b;
var added = a.Except(b);
var removed = b.Except(a);
回答by Kerry Perret
Here are two extension methods that might come handy when you need to find unordered differences between two IEnumerable (it's more or less the same as the answer given by leppie wrapper into extension methods):
当您需要找到两个 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();
}
}
回答by Robin Qiu
Another useful API, get the symmetric difference:
另一个有用的API,获取对称差异: