2012-04-16 22 views
7

Cuál es la manera más fácil de eliminar elementos que coinciden con alguna condición de una lista y luego, obtener esos elementos.LINQ: RemoveAll y obtener elementos eliminados

que puede pensar en algunas maneras, no sé cual es la mejor:

var subList = list.Where(x => x.Condition); 
list.RemoveAll(x => x.Condition); 

o

var subList = list.Where(x => x.Condition); 
list.RemoveAll(x => subList.Contains(x)); 

Es todo esto una de las mejores maneras? Si lo es, ¿cuál? Si no es así, ¿cómo debería hacerlo?

Respuesta

4

Me gustaría ir con la primera opción para facilitar la lectura, con la nota que se debe materializar la primera lista, o si no se pierden los mismos elementos que está tratando de seleccionar en la línea siguiente:

var sublist = list.Where(x => x.Condition).ToArray(); 
list.RemoveAll(x => x.Condition); 

El segundo ejemplo es O (n^2) sin ninguna razón y el último está perfectamente bien, pero es menos legible.

Editar: ahora que volví a leer su último ejemplo, tenga en cuenta que, como está escrito ahora, sacará todos los demás elementos. Falta la verificación de condición y la línea de eliminación debería ser realmente list.RemoveAt(i--); porque el elemento i+1 se convierte en el elemento i después de la eliminación, y cuando incrementa i, se está salteando.

+0

En realidad es O (n^3), pero estoy suponiendo que la falta de materialización simplemente deslizó su mente;) – Blindy

+0

¿Se eliminarán los elementos (tal como lo escribí) de subList con la segunda instrucción? : O – Diego

+0

Er nunca quitas de 'sublist', ni lo intentas si lo leo correctamente. – Blindy

2

Me gusta usar un enfoque de programación funcional (solo hacer cosas nuevas, no modificar cosas existentes). Una de las ventajas de ToLookup es que puede manejar más de una división bidireccional de los elementos.

ILookup<bool, Customer> lookup = list.ToLookup(x => x.Condition); 
List<Customer> sublist = lookup[true].ToList(); 
list = lookup[false].ToList(); 

O si necesita modificar la instancia original ...

list.Clear(); 
list.AddRange(lookup[false]); 
+0

Creo que es muy complejo (y casi sin conocimiento, creo que no es realmente el rendimiento). ¿Tiene esto alguna ventaja? – Diego

+0

La condición se evalúa exactamente una vez por artículo.La instancia de lista no se modifica, lo que puede ser una gran ventaja si esa instancia de lista se comparte entre subprocesos. –

Cuestiones relacionadas