views:

142

answers:

3

I'm refactoring this code and was trying to think of a simple linq expression to populate this Dictionary.

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

I could only come up with implementing a custom IEqualityComparer and using that in an expression such as this...

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

Is there a way to do it all inline without the custom IEqualityComparer? Thanks in advance.

+5  A: 
    var qry = headers.GroupBy(row => row.DestinationLocation)
        .ToDictionary(grp => grp.Key, grp => grp.First());

or (equivalent):

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

I wonder, though, if your current foreach code isn't already better - it doesn't buffer the ones it intends to drop, for example.

Marc Gravell
Good answer. I think you are right that the current code is more clear.
Jace Rhea
+1  A: 
var headerLocationLookup = PopulateHeaders()
    .Aggregate(new Dictionary<string, IHeaderRecord>(), (header, d) => {
     if(d.ContainsKey(header.DestinationLocation)) 
      d[header.DestinationLocation] = header;

     return d;
    });

I don't think this is any clearer than the existing code though.

Lee
+3  A: 

I wrote a blog post a while back that shows you how you can create overloads of Distinct that use a lambda expression as the key selector instead of a custom comparer, which would let you write:

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

It does use a custom comparer underneath, but the extension method constructs that stuff for you, and makes it much easier to read.

Greg Beech
That it very pleasing on the eye.
Marc Gravell