2009-12-17 10 views
6

Estoy refaccionando este código y estaba tratando de pensar en una expresión linq simple para poblar este Diccionario.Ayuda Recolección de Linqifying al Diccionario

IEnumerable<IHeaderRecord> headers = PopulateHeaders(); 
var headerLocationLookup = new Dictionary<string, IHeaderRecord>(); 

foreach (var header in headers) 
{ 
//destination locations can repeat, if they do, dictionary should only contain the first header associated with a particular location 
    if (!headerLocationLookup.ContainsKey(header.DestinationLocation)) 
    { 
     headerLocationLookup[header.DestinationLocation] = header; 
    } 
} 

sólo podía llegar a la implementación de una costumbre IEqualityComparer y el uso que, en una expresión como esta ...

headers.Distinct(new CustomComparer()).ToDictionary(); 

¿Hay una manera de hacerlo todo en línea sin la costumbre IEqualityComparer? Gracias por adelantado.

Respuesta

13
var qry = headers.GroupBy(row => row.DestinationLocation) 
     .ToDictionary(grp => grp.Key, grp => grp.First()); 

o (equivalente):

var dictionary = (from row in headers 
       group row by row.DestinationLocation) 
       .ToDictionary(grp => grp.Key, grp => grp.First()); 

Me pregunto, sin embargo, si su actual código foreach no está ya mejor - no almacena los que tiene intención de caer, por ejemplo.

+1

Buena respuesta. Creo que tienes razón en que el código actual es más claro. –

2
var headerLocationLookup = PopulateHeaders() 
    .Aggregate(new Dictionary<string, IHeaderRecord>(), (header, d) => { 
     if(d.ContainsKey(header.DestinationLocation)) 
      d[header.DestinationLocation] = header; 

     return d; 
    }); 

No creo que esto sea más claro que el código existente.

5

me escribió una blog post hace un tiempo que le muestra cómo se puede crear sobrecargas de distintas que utilizan una expresión lambda como el selector de llave en lugar de un comparador de costumbre, lo que permitirá escribir:

headers.Distinct(h => h.DestinationLocation) 
     .ToDictionary(h => h.DestinationLocation); 

Se usa un comparador personalizado debajo, pero el método de extensión construye esas cosas para usted y hace que sea mucho más fácil de leer.

+1

Eso es muy agradable a la vista. –