Sorting a Dictionary on a List of Keys

I can almost hear you thinking: “What super-weird problem are you trying to solve!?” Well… it is kind of an abstract one! Imagine you have a dictionary of objects and a separate list of keys in a certain order. Now suppose you want an ordered dictionary based on the list of keys.

We have a dictionary with objects with the color as key. 
Now we would like to sort the objects in the same order as the list of colors.
Note: not all colors are in the list.

According to the documentation the order of the generic Dictionary<TKey, TValue> is not guaranteed. When I tested the order, it looked like it was the same as the insertion order. If you need a sorted dictionary the SortedDictionary<TKey, TValue> is your man.

Building a KeyComparer

So we basically need to influence the sorting-mechanism of the SortedDictionary. This can be done by implementing an IComparer that will do the sorting based on the list of keys. We should adhere to the following rules:

  • The position of each key in the list should determine the position in the sorted dictionary.
  • If a key has a lower position in the list, the position in the dictionary should be lower as well.
  • If a key is not in the list, just put it on the bottom of the dictionary.

Converted into code, it will look like this.

Implementing the comparer can be quite confusing (it was for me). Fortunately there is documentation. To make things less confusing I used constants instead of integers. Another trick is to make the first parameter the “hero” and think of the compare as deciding if our hero should go to the TOP or BOTTOM of the sorted dictionary.

The result

Now let’s compare what happens if we insert a few values in a normal dictionary versus a sorted dictionary (with the new sorter and a list of fields to sort on):

Check how new key/value items are added to both dictionaries. 
The content of the dictionaries are listed in the [key, value] format.

Getting some extensions

I love Linq and it feels like this sorting-feature should be a Linq-like extension as well:

So that’s it, we can sort. The world has order again.


Originally published at keestalkstech.com on October 13, 2018.