Converting a sequence of objects into a Lookup with LINQ C#
February 5, 2016 Leave a comment
A Lookup in .NET is one of the lesser known data structures. It is similar to a Dictionary but the keys are not unique. You can insert multiple elements for the same key.
Say you have the following object and collection:
public class Singer
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int BirthYear { get; set; }
}
IEnumerable<Singer> singers = new List<Singer>()
{
new Singer(){Id = 1, FirstName = "Freddie", LastName = "Mercury", BirthYear=1964}
, new Singer(){Id = 2, FirstName = "Elvis", LastName = "Presley", BirthYear = 1954}
, new Singer(){Id = 3, FirstName = "Chuck", LastName = "Berry", BirthYear = 1954}
, new Singer(){Id = 4, FirstName = "Ray", LastName = "Charles", BirthYear = 1950}
, new Singer(){Id = 5, FirstName = "David", LastName = "Bowie", BirthYear = 1964}
};
You can group the singers into an ILookup as follows:
ILookup<int, Singer> singersByBirthYear = singers.ToLookup(s => s.BirthYear);
IEnumerable<Singer> filtered = singersByBirthYear[1964];
foreach (Singer s in filtered)
{
Console.WriteLine(s.LastName);
}
…which outputs “Mercury” and “Bowie”.
You can also set the elements inserted into the ILookup using an overloaded variant where you specify the element selector:
ILookup<int, string> singerNamesByBirthYear = singers.ToLookup(s => s.BirthYear, si => string.Concat(si.LastName, ", ", si.FirstName));
IEnumerable<string> filtered2 = singerNamesByBirthYear[1964];
foreach (string s in filtered2)
{
Console.WriteLine(s);
}
…which prints “Mercury, Freddie” and “Bowie, David”.
You can view all LINQ-related posts on this blog here.