LINQ: Quickly Create Dictionaries with ToDictionary
Donn Felker recently blogged about a neat little extension method in LINQ called Any(). If you simply want to know if a sequence contains any elements, many people use ".Count() > 0" which will walk the entire sequence to compute the count whereas .Any() will stop walking as soon as it finds a single element. Easy and much more efficient.
It reminded me about another LINQ method I've used from time to time: ToDictionary(). This method will allow you to quickly create a dictionary from any IEnumerable<T>. Let's start with some sample data that is in a List<T>:
IList<Person> people = new List<Person>
{
new Person {FirstName = "Bob", LastName = "Smith", SSN = "1"},
new Person {FirstName = "Jane", LastName = "Doe", SSN = "2"},
new Person {FirstName = "Mike", LastName = "Johnson", SSN = "3"}
};
Converting this to a dictionary is pretty trivial without LINQ. Suppose we want to index these by SSN:
var d = new Dictionary<string, Person>();
foreach(var p in people)
{
d.Add(p.SSN, p);
}
But why waste our time doing all that when we can simply use LINQ's ToDictionary()? Just give it a lambda that selects the key and you're all set:
var indexedBySSN = people.ToDictionary(k => k.SSN);
Or perhaps you don't want the entire Person object. Maybe you just want a collection of last names indexed by Social Security Number (SSN). No problem --there's an overload that accepts two lambdas: one to select the key and one to select the value.
var lastNamesIndexedBySSN = people.ToDictionary(k => k.SSN, e => e.LastName);
There's also two more overloads that work the same as the two above, but allow you to also provide an IEqualityComparer<T> used to compare your keys.
Everyday I find more and more stuff in LINQ that helps me eliminate the mundane code and make my source more readable.