Make a case-insensitive dictionary in C#

[dictionary]

The example Use a Dictionary to store and retrieve items in C# shows how to use a dictionary to store and retrieve values with keys.

By default the Dictionary class is case-sensitive so the keys “Rod Stephens” and “rod stephens” are treated as two different values. For example, if you build a dictionary to look up phone numbers, the dictionary could hold two separate entries for “Rod Stephens” and “rod stephens,” which is probably not what you want.

The following code builds a dictionary that is case-insensitive so it treats “Rod Stephens” and “rod stephens” as the same key value.

Dictionary<string, string> dict =
    new Dictionary<string, string>(
        StringComparer.InvariantCultureIgnoreCase);

This example builds the dictionary and then tests it by adding and searching for a bunch of test items.

It then builds a regular case-sensitive dictionary and performs the same tests. Before it adds or searches for items, however, the code converts the key into lowercase. The result is similar to that given by the case-insensitive dictionary but, as you can see in the picture, using ToLower is significantly faster.

The following code shows how the program uses the case-sensitive dictionary with ToLower.

// Dictionary using ToLower.
dict = new Dictionary<string, string>();

// Add items.
for (int i = 0; i < num_items; i++)
{
    key = "Key " + i.ToString();
    key = key.ToLower();
    value = "Value " + i.ToString();
    if (!dict.ContainsKey(key)) dict.Add(key, value);
}

// Add duplicate items with different case.
for (int i = 0; i < num_items; i++)
{
    key = "key " + i.ToString();
    key = key.ToLower();
    value = "value " + i.ToString();
    if (!dict.ContainsKey(key)) dict.Add(key, value);
}

// Find items.
for (int i = 0; i < num_items; i++)
{
    key = "Key " + i.ToString();
    key = key.ToLower();
    if (dict.ContainsKey(key)) value = dict[key];
}

// Look for missing items.
for (int i = 0; i < num_items; i++)
{
    key = "Missing " + i.ToString();
    key = key.ToLower();
    if (dict.ContainsKey(key)) value = dict[key];
}

The code creates the new Dictionary. It then loops over the number of trials creating test keys and values. It uses ToLower to convert the keys into lower case and adds them to the Dictionary.

Next the code tries to add duplicate items to the Dictionary. The calls to ContainsKey prevent the code from adding these items because the code finds that they are already in the Dictionary.

The program then searches for the items and finally searches for some items that are not in the Dictionary. In all cases the code uses ToLower to ensure that the keys all have lower case. That way keys in upper, lower, or mixed are all treated as the same values.

The program’s code for using the case-insensitive Dictionary is similar except it doesn’t use the calls to ToLower.

Download the example to see all of the details and to experiment with the code.

Overall the version that uses ToLower is faster, although you need to remember to use ToLower in your code or the Dictionary could hold keys that contain uppercase letters.


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in controls, strings and tagged , , , , , , , , , , , , , , . Bookmark the permalink.

One Response to Make a case-insensitive dictionary in C#

  1. Skye says:

    Old article I know, but you should use StringComparer.OrdinalIgnoreCase, it’s one of the fastest comparer for the framework.

    Said so, if I use your program with the more fine-grained Stopwatch.StartNew() (.NET 4) and StringComparer.OrdinalIgnoreCase it’s a lil’ faster than ToLower or at least the same. That’ll benefit in eliminating ToLower in every place and even more it saves memory, cause strings are immutable.

Leave a Reply

Your email address will not be published. Required fields are marked *