DEV Community

mohamed Tayel
mohamed Tayel

Posted on

Understanding Dictionary Enumeration and Sorting in C#

Introduction

Dictionaries in C# are widely used for key-value storage and fast lookups. However, one common mistake developers make is assuming that dictionaries maintain a fixed order when enumerating. In this article, we will explore:

  • How dictionary enumeration works.
  • The limitations of relying on dictionary order.
  • How SortedDictionary<TKey, TValue> and SortedList<TKey, TValue> help maintain sorted order.
  • The best approach to sorting a dictionary by a custom property.
  • A complete console application demonstrating these concepts step by step.

1. Dictionary Enumeration: The Problem

A Dictionary<TKey, TValue> does not guarantee order when enumerating items. Let’s demonstrate this behavior with a simple example:

Step 1: Create a Console Application and Define a Dictionary

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        Dictionary<string, string> countries = new Dictionary<string, string>
        {
            { "US", "United States" },
            { "GB", "United Kingdom" },
            { "DE", "Germany" },
            { "FR", "France" },
            { "JP", "Japan" }
        };

        Console.WriteLine("Enumerating Dictionary:");
        foreach (var kvp in countries)
        {
            Console.WriteLine($"{kvp.Key}: {kvp.Value}");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Expected Output (Order May Vary)

Enumerating Dictionary:
GB: United Kingdom
US: United States
JP: Japan
DE: Germany
FR: France
Enter fullscreen mode Exit fullscreen mode

The order of enumeration is not guaranteed and may change across different runs. This is because Dictionary<TKey, TValue> is optimized for fast lookups, not ordering.


2. Using SortedDictionary

If we need to maintain a sorted order, we can use SortedDictionary<TKey, TValue>. This collection automatically sorts its items by key.

Step 2: Replace Dictionary with SortedDictionary

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        SortedDictionary<string, string> sortedCountries = new SortedDictionary<string, string>
        {
            { "US", "United States" },
            { "GB", "United Kingdom" },
            { "DE", "Germany" },
            { "FR", "France" },
            { "JP", "Japan" }
        };

        Console.WriteLine("\nEnumerating SortedDictionary:");
        foreach (var kvp in sortedCountries)
        {
            Console.WriteLine($"{kvp.Key}: {kvp.Value}");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Output (Always Sorted by Key)

Enumerating SortedDictionary:
DE: Germany
FR: France
GB: United Kingdom
JP: Japan
US: United States
Enter fullscreen mode Exit fullscreen mode

Key Takeaway:

SortedDictionary automatically maintains key-based sorting.

❌ However, if we need sorting based on values (e.g., country names), SortedDictionary won’t help.


3. Using SortedList

Another option is SortedList<TKey, TValue>. It functions similarly to SortedDictionary, but stores data in an internal array instead of a balanced tree.

Step 3: Replace SortedDictionary with SortedList

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        SortedList<string, string> sortedListCountries = new SortedList<string, string>
        {
            { "US", "United States" },
            { "GB", "United Kingdom" },
            { "DE", "Germany" },
            { "FR", "France" },
            { "JP", "Japan" }
        };

        Console.WriteLine("\nEnumerating SortedList:");
        foreach (var kvp in sortedListCountries)
        {
            Console.WriteLine($"{kvp.Key}: {kvp.Value}");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Output (Always Sorted by Key)

Enumerating SortedList:
DE: Germany
FR: France
GB: United Kingdom
JP: Japan
US: United States
Enter fullscreen mode Exit fullscreen mode

Comparison Between SortedDictionary and SortedList

| Feature | SortedDictionary | SortedList |
|---------|-----------------|------------|
| Sorting | By key (auto) | By key (auto) |
| Memory Usage | Higher (tree structure) | Lower (array-based) |
| Insert/Delete Performance | Faster for frequent changes | Slower for frequent changes |
| Lookup Speed | O(log n) | O(log n) |

Key Takeaway:

SortedList uses less memory but performs worse when inserting/removing items frequently.

SortedDictionary is better for frequent modifications but uses more memory.


4. Sorting by a Custom Property (Best Approach)

If we want to sort by country name (value) instead of the key, we cannot rely on SortedDictionary or SortedList. Instead, we should sort a list manually.

Step 4: Sorting by Country Name

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        Dictionary<string, string> countries = new Dictionary<string, string>
        {
            { "US", "United States" },
            { "GB", "United Kingdom" },
            { "DE", "Germany" },
            { "FR", "France" },
            { "JP", "Japan" }
        };

        Console.WriteLine("\nSorting by Country Name:");
        var sortedByValue = countries.OrderBy(kvp => kvp.Value).ToList();

        foreach (var kvp in sortedByValue)
        {
            Console.WriteLine($"{kvp.Key}: {kvp.Value}");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Output (Sorted by Country Name)

Sorting by Country Name:
DE: Germany
FR: France
GB: United Kingdom
JP: Japan
US: United States
Enter fullscreen mode Exit fullscreen mode

Key Takeaway:

✅ Sorting a list manually using OrderBy(kvp => kvp.Value) is the best way to sort dictionaries by value.

SortedDictionary and SortedList only sort by key, not value.


Conclusion

  • Dictionary<TKey, TValue> does not guarantee order when enumerating.
  • SortedDictionary<TKey, TValue> and SortedList<TKey, TValue> maintain sorted order, but only by key.
  • If sorting by value is needed, use LINQ’s OrderBy on a list.
  • SortedDictionary vs. SortedList:
    • SortedDictionary is better for frequent insertions/deletions.
    • SortedList is more memory-efficient but slower for updates.

Final Thoughts

✅ Use Dictionary<TKey, TValue> for fast lookups.

✅ Use SortedDictionary<TKey, TValue> for ordered keys.

✅ Use OrderBy(kvp => kvp.Value) when sorting by values.

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more