for - Linq encuentra diferencias en dos listas
linq set value for all items in list c# (4)
Aquí está la versión que tiene O (n) complejidad, siempre que sus secuencias estén ordenadas:
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);
}
Tengo dos listas de miembros como esta:
Antes: Peter, Ken, Julia, Tom.
Después: Peter, Robert, Julia, Tom
Como puedes ver, Ken está fuera y Robert está dentro.
Lo que quiero es detectar los cambios. Quiero una lista de lo que ha cambiado en ambas listas. ¿Cómo puede ayudarme linq?
Como alternativa a las respuestas de linq, que tienen que pasar las dos listas dos veces, use HashSet.SymmetricExceptWith() :
var difference = new HashSet(before);
difference.SymmetricExceptWith(after);
Podría ser considerablemente más eficiente.
De otra manera:
before.Union(after).Except(before.Intersect(after))
Su pregunta no está completamente especificada, pero supongo que está buscando las diferencias como conjuntos (es decir, el orden no importa). Si es así, quieres la diferencia simétrica de los dos conjuntos. Puedes lograr esto usando Enumerable.Except
. Enumerable.Except
:
before.Except(after).Union(after.Except(before));