Dictionary is a handy class. It’s a collection of key-value pairs. It is a hash table which means that it has to have unique keys (according to equality comparer). Each key is mapped to a value. Retrieving a value by key is very fast. There are many things you can do with it. In this article I’m going to show you some tricks that may come in handy sometimes.
Initializing dictionary
In cases when you already have some predefined data you can initialize it using collection initializer.
|
|
How to create case-insensitive dictionary
By default dictionaries are case sensitive, which means that dictionary["A"]
and dictionary["a"]
are different entries. You can however use overloaded constructor to make it case insensitive.
|
|
Get keys/values
You can get keys or values alone, it’s already built-in.
|
|
Looping over key-value pairs
Dictionary
implements IEnumerable<TKey, TValue>
so you can loop over it.
|
|
Testing if dictionary contains key or value
You can test it by using built-it methods.
|
|
Dictionary and LINQ
Good news is that you can still use Linq with dictionaries.
|
|
How to merge dictionaries in C#
Key point with merging dictionaries is that there can be duplicates and, as we know, it will cause an exception. So we need to remember that we have to deal with duplicaties. As for the code, there are a few ways to do that. I’ll show you simple LINQ based solution, but you could as well just enumerate of it and add key-value pairs to a new one.
You can either use Union or Concat. Union technically tries to remove duplicates, but it won’t work for Dictionaries, because default IEqualityComparer cannot handle it. You can provide custom comparer as a second argument to Union, but this is not the solution I like.
We’ll use Concat, but to prevent duplicates we’re going to group (using GroupBy) results by keys and pick first value. Then we’ll convert it back to dictionary using ToDictionary extension method (notice how we select value).
|
|
Replacing switch/case with dictionary
This technique came in hand multiple times for me. Instead of large switch/case statement you can construct a dictionary which will work in the same manner. This alone saves some space. But if we take into account that we can add new entires to it during application execution then we have more elastic solution than (stiff) switch/case.
Here’s and example of mapping http codes to messages.
|
|
Sorting a dictionary
Technically order of elements in a Dictionary is non-deterministic, which means that we cannot rely on it. If you add a few elements and then enumerate over dictionary it can be in different order.
You can order a elements in dictionary, but you will receive a separate collection of type IOrderedEnumerable<TElement>
, the order of elements inside it will not be affected.
|
|
However there exists special SortedDictionary class, which sorts elements by keys. You can provide your own comparer implementation, refer to documentation.
|
|
Dictionary with ordered elements
There’s a specialized class for the purpose of having ordered items. It means that when you enumerate it, elements will always be in the same order as you added those inside it. It’s called OrderedDictionary and the order of items is guaranteed. It’s worth noting that there is no generic type version.
|
|