2010-07-05 12 views
24

Si quiero filtrar una lista de objetos contra un ID específico, puedo hacer esto:expresión lambda porque dentro de la lista

list.Where(r => r.Id == idToCompare); 

¿Qué pasaría si, en lugar de una sola idToCompare, tengo una lista de ID para comparar?

¿Cuál es la sintaxis para comparar con una lista predefinida? Algo así como:

int[] listofIds = GetListofIds(); 

list.Where(r => r.Id "in listofIds"); 

Respuesta

46

Si listOfIds es una lista, esto va a funcionar, pero, List.Contains() es una búsqueda lineal, así que esto no es muy eficiente.

Le conviene guardar los identificadores que desea buscar en un contenedor adecuado para la búsqueda, como Set.

List<int> listOfIds = new List(GetListOfIds()); 
lists.Where(r=>listOfIds.Contains(r.Id)); 
4

Se puede utilizar el método contains() extensión:

list.Where(r => listofIds.Contains(r.Id)) 
19
var query = list.Where(r => listofIds.Any(id => id == r.Id)); 

Otro enfoque, útil si la matriz listOfIds es grande:

HashSet<int> hash = new HashSet<int>(listofIds); 
var query = list.Where(r => hash.Contains(r.Id)); 
+2

utiliza con Entity Framework (y, posiblemente, LINQ to SQL), en realidad esto se traducirá en "SELECT * FROM Table donde Id en (1,2,3,4) ", lo que resulta en un solo viaje al servidor. –

+0

@IgorZevaka - si va a consultar el DB usando EF, preferiría usar SortedSet (que es una especie de superconjunto de HashSet). También es único, como HashSet, pero también ordenado. Luego indexaré mi columna Db en la que voy a ejecutar la cláusula 'where'. Eso será significativamente más rápido en datos de gran tamaño. – sandiejat

0

me gustaría ver en el Operador de unión:

from r in list join i in listofIds on r.Id equals i select r 

No estoy seguro de cómo se optimizaría esto con los métodos Contiene, pero al menos le da al compilador una mejor idea de lo que estás tratando de hacer. También está semestralmente más cerca de lo que estás tratando de lograr.

Editar: sintaxis del método de extensión esté completo (ahora que he averiguado):

var results = listofIds.Join(list, i => i, r => r.Id, (i, r) => r); 
+1

Estaba a punto de publicar la misma respuesta (aunque usando la sintaxis del método de extensión, pero eso es simplemente preferencia personal). Y sí, 'join' está más optimizado que' Contains', ya que construye una tabla hash en memoria de las teclas en ambos lados en lugar de hacer una búsqueda secuencial en 'listOfIds' para cada miembro de' list'. –

+0

@Anthony Pegram: Gracias, acabo de descubrirlo y borré mi comentario, lo siento. Como referencia, dije que no podía entender la sintaxis y pedí ayuda – TheEvilPenguin

Cuestiones relacionadas