Search code examples
c#dictionarycase-insensitive

How to get original case key by case insensitive key in Dictionary<string, int>


There is Dictionary:

var dictionary1 = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)
    {{"abc1", 1}, {"abC2", 2}, {"abc3", 3}};

I can get a value:

var value = dictionary1["Abc2"];

If search key "Abc2" I need to get the original key "abC2" and value 2.

How to get original case key by case insensitive key?


Solution

  • You can't do that, unfortunately. It would be entirely reasonable for Dictionary<TKey, TValue> to expose a bool TryGetEntry(TKey key, KeyValuePair<TKey, TValue> entry) method, but it doesn't do so.

    As stop-cran suggested in comments, the simplest approach is probably to make each value in your dictionary a pair with the same key as the key in the dictionary. So:

    var dictionary = new Dictionary<string, KeyValuePair<string, int>>(StringComparer.OrdinalIgnoreCase)
    {
        // You'd normally write a helper method to avoid having to specify
        // the key twice, of course.
        {"abc1", new KeyValuePair<string, int>("abc1", 1)},
        {"abC2", new KeyValuePair<string, int>("abC2", 2)},
        {"abc3", new KeyValuePair<string, int>("abc3", 3)}
    };
    if (dictionary.TryGetValue("Abc2", out var entry))
    {
        Console.WriteLine(entry.Key); // abC2
        Console.WriteLine(entry.Value); // 2
    }
    else
    {
        Console.WriteLine("Key not found"); // We don't get here in this example
    }
    

    If this is a field in a class, you could write helper methods to make it simpler. You could even write your own wrapper class around Dictionary to implement IDictionary<TKey, TValue> but add an extra TryGetEntry method, so that the caller never needs to know what the "inner" dictionary looks like.