Converting a sequence to a dictionary using the ToDictionary LINQ operator
February 2, 2016 Leave a comment
Say you have a sequence of objects that you’d like to convert into a Dictionary for efficient access by key. Ideally the objects have some kind of “natural” key for the dictionary such as an ID:
public class Singer { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } } IEnumerable<Singer> singers = new List<Singer>() { new Singer(){Id = 1, FirstName = "Freddie", LastName = "Mercury"} , new Singer(){Id = 2, FirstName = "Elvis", LastName = "Presley"} , new Singer(){Id = 3, FirstName = "Chuck", LastName = "Berry"} , new Singer(){Id = 4, FirstName = "Ray", LastName = "Charles"} , new Singer(){Id = 5, FirstName = "David", LastName = "Bowie"} };
It’s easy to create a singers dictionary from this sequence:
Dictionary<int, Singer> singersDictionary = singers.ToDictionary(s => s.Id); Console.WriteLine(singersDictionary[2].FirstName);
You supply the key selector as the argument to the operator, which will be the key of the dictionary. The operator will throw an ArgumentException if you’re trying to add two objects with the same key. Example:
return new List<Singer>() { new Singer(){Id = 1, FirstName = "Freddie", LastName = "Mercury"} , new Singer(){Id = 1, FirstName = "Elvis", LastName = "Presley"} , new Singer(){Id = 3, FirstName = "Chuck", LastName = "Berry"} , new Singer(){Id = 4, FirstName = "Ray", LastName = "Charles"} , new Singer(){Id = 5, FirstName = "David", LastName = "Bowie"} };
There are two singers with id = 1 which will cause an exception when it’s Elvis’ turn to be inserted into the dictionary.
The ToDictionary operator has an overload which allows you to change the elements inserted into the dictionary. Say you’d like to have the id as the key but only the last name as the value. You can do like this:
Dictionary<int, string> singersDictionaryNames = singers.ToDictionary(s => s.Id, si => string.Format("Last name: {0}", si.LastName)); Console.WriteLine(singersDictionaryNames[2]);
You can view all LINQ-related posts on this blog here.