He estado en algunos artículos de StackOverFlow sobre esto (este en particular) Y por alguna razón mi caso es diferente. He usado la respuesta de Tony The Lion para intentar obtener una lista de objetos que tienen valores de propiedad diferentes, sin éxito. Esto, sin embargo, funciona:

List<Task> changedTasksWorking = new List<Task>();
for (int x = 0; x < originalTaskList.Count; x++)
{
    if (originalTaskList[x].ActiveFlag != newTaskList[x].ActiveFlag)
    {
        changedTasksWorking.Add(newTaskList[x]);
    }
}

Lo siguiente es lo que pensé que me proporcionaría el mismo resultado. Pero donde la lista devuelta debería ser igual a 1, en su lugar es igual a cero. Cuando flipo la comparación de la propiedad con != y retire la condición ni la condición en la lista interna, obtengo todos los objetos de la lista:

List<Task> notWork = oL.Where(o => newL.Any(n => o.ActiveFlag != n.ActiveFlag)).ToList();

Siento que estoy tomando pastillas locas. Mirando el forro anterior que debería darme lo que estoy pidiendo. Tal vez haya entendido mal cómo los métodos LINQ Where y Any están interactuando.

1
Iofacture 1 jul. 2019 a las 01:08

1 respuesta

La mejor respuesta

Su enfoque de LINQ propuesto es completamente diferente de lo que parece que realmente está tratando de hacer. En particular, de acuerdo con su ejemplo original, tiene dos listas que están exactamente sincronizadas entre sí. Es decir. Tienen el mismo número de elementos, y cada elemento de una lista corresponde exactamente al mismo elemento en la misma posición en la otra lista.

Su código LINQ, por otro lado, analiza cada elemento en una lista a la vez, y para cada uno de esos elementos, busca en la otra lista para uno que tiene un valor de propiedad que no coincide. En otras palabras, si la lista newL tiene elementos de todos los valores posibles de ActiveFlag, por supuesto, devolverá todos los elementos de oL, porque para cada elemento en oL, Linq es capaz de encontrar un elemento en newL donde el valor de la propiedad no coincide.

Hay al menos un par de alternativas obvias que utilizan LINQ que hará en realidad funcionan:

  1. Use la sobrecarga para Where() que pase el índice al delegado predicado:
List<Task> changedTasks = newTaskList
    .Where((n, i) => n.ActiveFlag != originalTaskList[i].ActiveFlag).ToList();
  1. Use Enumerable.Zip() para emparejar elementos en una nueva secuencia y filtro que:
List<Task> changedTasks = originalTaskList
    .Zip(newTaskList, (o, n) => o.ActiveFlag != n.ActiveFlag ? n : null)
    .Where(n => n != null).ToList();

Cualquiera de ellos debería funcionar bien.

4
Peter Duniho 30 jun. 2019 a las 22:26