In this article, we are going to learn how to sort the values in the dictionary by their value.
Let’s begin.
Sorting by Value in Dictionary
In C#, the Dictionary type is used to hold a collection of key-value pairs. Since the dictionary uses a hash table internally, the key lookup is very fast. In certain scenarios, we might want to enumerate all the key-value pairs in the dictionary. But, ordered by their value.
In order to achieve this, let’s look at different ways, and then let’s do some benchmarks to know which is the most efficient way.
Before proceeding, we’ll create a simple dictionary of unordered values:
var dictionary = new Dictionary<string, string> { { "1", "apple" }, { "2", "orange" }, { "3", "banana" }, { "4", "grape" } };
In this case, we are using the string
type for both key and value in the dictionary. Henceforth, the dictionary’s type is Dictionary<string,string>
.
Using the OrderBy() Method
The first way is to use the OrderBy()
method available in LINQ. We can directly invoke this method on the dictionary:
var sortedKeyValuePairs = dictionary.OrderBy(x => x.Value).ToList();
Here, we are passing a lambda expression x => x.Value
to the OrderBy()
method. This will order the dictionary by its value.
After ordering, we convert it to a list using the ToList()
method. When we check the type of the list, it will be List<KeyValuePair<string,string>>
. Here, each item in the list is represented as a KeyValuePair<TKey,TValue>
type.
The reason we are not converting the ordered items back to the Dictionary<string,string>
is that the dictionary cannot guarantee the same order upon enumeration. Hence, we need to preserve the ordered items in a list.
When we print the items in the list, we can see the ordered output:
1 apple 3 banana 4 grape 2 orange
If we want to sort the values in descending order, we can use the OrderByDescending()
method.
Using LINQ Query Expression
An alternative way is to use the LINQ Query Expression syntax. Let’s quickly look at how to do it:
var sortedKeyValuePairs = ( from keyValuePair in dictionary orderby keyValuePair.Value ascending select keyValuePair ).ToList();
Here, we are using the orderby
clause on the keyValuePair.Value
property. Additionally, we can use ascending
or descending
clause as per our needs.
Using the Sort() Method
The next way is to use the Sort()
method. To use this method we need to first convert the dictionary to a list:
var sortedKeyValuePairs = dictionary.ToList();
And then, we can invoke the Sort()
method on this list:
sortedKeyValuePairs.Sort((pair1, pair2) => pair1.Value.CompareTo(pair2.Value));
Please note that the Sort()
method does not have a return value. It accepts a Comparision<T>
delegate type where we can pass the lambda expression. The Sort()
method uses this expression to sort the list.
Comparing Performance of Methods
So far so good. Now, let’s benchmark these three ways and find out the most performant way. We’ll use the BenchmarkDotNet library to do the benchmark for us.
We’ll use three different dictionary sizes (1000, 10,000, and 100,000) for the benchmark. Also, we populate the dictionary with 36 char GUID values:
public Dictionary<string, string> Generate(int count) { var dictionary = new Dictionary<string, string>(); for (var i = 0; i < count; i++) { dictionary.Add($"{i}", Guid.NewGuid().ToString()); } return dictionary; }
Let’s run the benchmark and wait for the result:
| Method | dictionaryInput | Mean | Error | StdDev | |-------------------------------------------- |---------------- |-------------:|------------:|------------:| | SortDictionaryValueUsingLinqOrderBy | 1000 items | 514.5 us | 6.87 us | 6.42 us | | SortDictionaryValueUsingLinqQueryExpression | 1000 items | 529.3 us | 7.73 us | 7.23 us | | SortDictionaryValueUsingSortMethod | 1000 items | 619.2 us | 2.82 us | 2.20 us | | SortDictionaryValueUsingLinqOrderBy | 10000 items | 7,580.4 us | 78.67 us | 73.59 us | | SortDictionaryValueUsingLinqQueryExpression | 10000 items | 7,595.8 us | 32.51 us | 27.15 us | | SortDictionaryValueUsingSortMethod | 10000 items | 8,993.0 us | 31.95 us | 26.68 us | | SortDictionaryValueUsingLinqOrderBy | 100000 items | 117,477.4 us | 548.88 us | 486.57 us | | SortDictionaryValueUsingLinqQueryExpression | 100000 items | 120,683.5 us | 881.49 us | 824.54 us | | SortDictionaryValueUsingSortMethod | 100000 items | 126,789.7 us | 1,181.45 us | 1,047.32 us |
From the result, we can see that the OrderBy()
method is the fastest with a mean of 514.5 us, closely followed by the LINQ Query Expression with a mean of 529.3 us, and later followed by the Sort()
method with a mean of 619.2 us for 1000 items in the dictionary. When the dictionary size increases, the time also increases proportionately. It is also important to note that there is no significant time difference between the three methods for smaller dictionaries.
Earlier we saw that the OrderBy()
method is the simplest to implement and from the benchmark, we know that it is also the fastest. Therefore, it is a preferred option to sort the dictionary by value.
Conclusion
In this article, we’ve learned some of the different ways to sort a dictionary by value in C#. Later, from the benchmark, we found that the OrderBy()
method is the fastest of all. However, we also found that there’s no significant difference between the three methods. If you’d like to learn more about sorting objects in lists, check out our article Sort List by Property in the Object in .NET.
The SortDictionaryValueUsingLinqQueryExpression would literally be translated by the compiler into:
That last
Select()
does nothing except add the little bit of overhead we see. I make a point of only using the query syntax when I’m using theselect
to project the data into a different object.Thank you James for this info.