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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With