【发布时间】:2011-01-25 03:32:23
【问题描述】:
我有两个这样的成员列表:
之前:彼得、肯、朱莉娅、汤姆
之后:彼得、罗伯特、朱莉娅、汤姆
如您所见,Ken 出局,Robert 入局。
我想要的是检测变化。我想要两个列表中发生变化的列表。 linq 对我有什么帮助?
【问题讨论】:
-
我认为你需要多定义一点“改变”。例如,项目顺序的改变对你来说是“改变”吗?
我有两个这样的成员列表:
之前:彼得、肯、朱莉娅、汤姆
之后:彼得、罗伯特、朱莉娅、汤姆
如您所见,Ken 出局,Robert 入局。
我想要的是检测变化。我想要两个列表中发生变化的列表。 linq 对我有什么帮助?
【问题讨论】:
这是具有 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);
}
【讨论】:
您的问题没有完全指定,但我假设您正在寻找集合中的差异(也就是说,排序无关紧要)。如果是这样,您需要两组中的symmetric difference。您可以使用Enumerable.Except 实现此目的:
before.Except(after).Union(after.Except(before));
【讨论】:
作为必须通过两个列表两次的 linq 答案的替代方法,请使用 HashSet.SymmetricExceptWith():
var difference = new HashSet(before);
difference.SymmetricExceptWith(after);
可能会更有效率。
【讨论】:
另一种方式:
before.Union(after).Except(before.Intersect(after))
【讨论】: