Compare case-insensitive dictionaries in C#

The example Use a Dictionary object to store and look up items in C# shows how 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 dict =
    new Dictionary(StringComparer.InvariantCultureIgnoreCase);

This example builds such a 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();
start_time = DateTime.Now;

// 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.
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];
}

elapsed = DateTime.Now - start_time;
txtToLower.Text = elapsed.TotalSeconds.ToString("0.00") + " sec";
txtToLower.Refresh();

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 to 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 uses ToLower to convert all of the keys to lower case.

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 so keys in upper or lower case will be treated as the same values by the Dictionary.

The program's code for using the case-insensitive Dictionary is similar except it doesn't use the calls to ToLower because the Dictionary treats similar keys with different cases as matching.

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.

   

 

What did you think of this article?




Trackbacks
  • No trackbacks exist for this post.
Comments
  • No comments exist for this post.
Leave a comment

Submitted comments are subject to moderation before being displayed.

 Name

 Email (will not be published)

 Website

Your comment is 0 characters limited to 3000 characters.