2009-12-17 3 views
6

Je suis en train de refactoriser ce code et essayait de penser à une expression linq simple pour peupler ce dictionnaire.Aide Linqifying collection à Dictionnaire

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; 
    } 
} 

Je ne pouvais venir avec la mise en œuvre d'une mesure IEqualityComparer et en utilisant que dans une expression comme celle-ci ...

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

Est-il possible de le faire tout en ligne sans IEqualityComparer sur mesure? Merci d'avance.

Répondre

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

ou (équivalent):

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

Je me demande, cependant, si votre code foreach actuel n'est pas déjà mieux - il ne cache pas ceux qu'il a l'intention de laisser tomber, par exemple.

+1

Bonne réponse. Je pense que vous avez raison de dire que le code actuel est plus clair. –

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

     return d; 
    }); 

Je ne pense pas que ce soit plus clair que le code existant.

5

J'ai écrit un blog post un certain temps que vous montre comment vous pouvez créer des surcharges de Distinct qui utilisent une expression lambda comme le sélecteur à clé au lieu d'un comparateur personnalisé, qui vous permettra d'écrire:

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

Il utilise un comparateur personnalisé en dessous, mais la méthode d'extension construit ce truc pour vous, et le rend beaucoup plus facile à lire.

+1

Que c'est très agréable sur l'oeil. –

Questions connexes