c# Dictionary: making the Key case-insensitive through declarations
Asked Answered
C

2

74

I have a Dictionary<string, object> dictionary. It used to be Dictionary<Guid, object> but other 'identifiers' have come into play and the Keys are now handled as strings.

The issue is that the Guid keys from my source data are coming as VarChar, so now a key of "923D81A0-7B71-438d-8160-A524EA7EFA5E" is not the same as "923d81a0-7b71-438d-8160-a524ea7efa5e" (wasn't a problem when using Guids).

What's really nice (and sweet) about the .NET framework is that I can do this:

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

And that works great. But what about a nested Dictionary? Like the following:

Dictionary<int, Dictionary<string, CustomClass>> _customRecordSet 
    = new  Dictionary<int, Dictionary<string, CustomClass>>();

How would I specify the string comparer on a nested dictionary like this?

Calandracalandria answered 13/7, 2011 at 8:38 Comment(5)
Just a hint, you may want to reconsider the use of StringComparer.InvariantCultureIgnoreCase. This comparer is slow, as it would compare strings using character classes to overcome cross-cultural differences. This means that the word Straße will be treated as equal to Strasse and vice-versa. I am assuming you do not want such behavior and if performance is crucial (if you are implementing something like a cache layer over a database) then you'd be better off by using StringComparer.OrdinalIgnoreCase. The ordinal comparer is the fastest string comparer the .NET framework can offer.Wishful
Possible duplicate of Case insensitive access for generic dictionaryLyonnesse
Really @avs099? That post you've linked to is a year younger than this one. Did you even notice?Horsehair
@AustinWBryan: "Possible duplicate" is a way to clean-up - to close similar questions and keep one with the best answers. The date is not essential. See Should I vote to close a duplicate question, even though it's much newer, and has more up to date answers?Merri
Related post - Case-INsensitive Dictionary with string key-type in C#Arvillaarvin
S
82

When you add an element to the outer dictionary, you'll likely create a new instance of the nested dictionary, add it at this point, making use of the overloaded constructor that takes an IEqualityComparer<TKey>.

_customRecordSet.Add(0, new Dictionary<string, CustomClass>(StringComparer.InvariantCultureIgnoreCase));


Update 08/03/2017: Anecdotally, I read somewhere (I think in "Writing High-Performance .NET Code") that StringComparer.OrdinalIgnoreCase is more efficient when simply wanting to disregard the case of characters. This, however, is entirely unfounded by myself so YMMV.

Stivers answered 13/7, 2011 at 8:40 Comment(0)
B
8

You are going to have to initialize the nested dictionaries in order to use them. Just use the code you have above at that point.

Basically, you should have some code like this:

public void insert(int int_key, string guid, CustomClass obj)
{
    if (_customRecordSet.ContainsKey(int_key)
         _customRecordSet[int_key][guid] = obj;
    else
    {
         _customRecordSet[int_key] = new Dictionary<string, CustomClass> 
                                     (StringComparer.InvariantCultureIgnoreCase);
         _customRecordSet[int_key][guid] = obj;
    }
}
Boleslaw answered 13/7, 2011 at 8:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.