简体   繁体   中英

Help Linqifying collection to Dictionary

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.

    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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM