我有两个这样的成员列表:
之前:彼得,肯,朱莉娅,汤姆
之后:彼得,罗伯特,朱莉娅,汤姆
正如你所看到的,肯已经出局,罗伯特也在。
我想要的是检测变化。我想要列出两个列表中已更改的内容。 linq如何帮助我?
答案 0 :(得分:28)
您的问题尚未完全明确,但我认为您正在寻找差异(即排序无关紧要)。如果是这样,您需要两组中的symmetric difference。您可以使用Enumerable.Except
:
before.Except(after).Union(after.Except(before));
答案 1 :(得分:21)
作为linq答案的替代方案,必须两次传递两个列表,请使用HashSet.SymmetricExceptWith():
var difference = new HashSet(before);
difference.SymmetricExceptWith(after);
可能效率更高。
答案 2 :(得分:5)
另一种方式:
before.Union(after).Except(before.Intersect(after))
答案 3 :(得分:2)
如果您的序列都是有序的,那么这是具有O(n)复杂度的版本:
public static IEnumerable<T> SymmetricDifference<T>(IEnumerable<T> coll1, IEnumerable<T> coll2, IComparer<T> cmp)
{
using (IEnumerator<T> enum1 = coll1.GetEnumerator())
using (IEnumerator<T> enum2 = coll2.GetEnumerator())
{
bool enum1valid = enum1.MoveNext();
bool enum2valid = enum2.MoveNext();
while (enum1valid && enum2valid)
{
int cmpResult = cmp.Compare(enum1.Current, enum2.Current);
if (cmpResult < 0)
{
yield return enum1.Current;
enum1valid = enum1.MoveNext();
}
else if (cmpResult > 0)
{
yield return enum2.Current;
enum2valid = enum2.MoveNext();
}
else
{
enum1valid = enum1.MoveNext();
enum2valid = enum2.MoveNext();
}
}
while (enum1valid)
{
yield return enum1.Current;
enum1valid = enum1.MoveNext();
}
while (enum2valid)
{
yield return enum2.Current;
enum2valid = enum2.MoveNext();
}
}
}
public static IEnumerable<T> SymmetricDifference<T>(IEnumerable<T> coll1, IEnumerable<T> coll2)
{
return SymmetricDifference(coll1, coll2, Comparer<T>.Default);
}