Using Hashtables/Dictionaries with string keys & Case Insensitive Searching

Eoin Campbell picture Eoin Campbell · May 13, 2009 · Viewed 17.6k times · Source

Wondering if this is possible.

We have an 3rd Party library that contains identification information about users...

The main interaction with the library is through a HashTable which is keyed with a string, and returns an Object Graph of information for that key.

The problem is, the key is obviously Case Sensitive, but what we get from the users browser doesn't necessarily match the case... (We often get the key fully lowercase'd)

I'm wondering if it's possible to do a case Insensitive key search against a hashtable.

e.g.

Hashtable ht = new Hashtable();
ht.Add("MyKey", "Details");

string result = ht["MyKey"];
string result = ht["MYKEY"];
string result = ht["mykey"];

On the off chance we could submit a support ticket to the company to add this functionality, are there any other DataStructures (i.e. the new generic collections/dictionaries) that support this functionality

Lastly, would it be possible to override the System.String GetHashCode() method, to make all case invariant strings return the same hashcode... e.g. I'm thinking this is a no goer as string is a sealed class

Cheers if anyone has any suggestions

Answer

SO User picture SO User · May 13, 2009

Code to make the hashtable comparisons case-insensitive

For 2.0, 3.0, 3.5

Hashtable ht = new Hashtable(StringComparer.InvariantCultureIgnoreCase);

You can get info on InvariantCultureIgnoreCase vs. OrdinalIgnoreCase on this SO link

OR

Hashtable ht = System.Collections.Specialized.CollectionsUtil.CreateCaseInsensitiveHashtable();

Because case-insensitive dictionary collection is such a common use, the .NET Framework has a CollectionUtil class that supports creating Hashtable and SortedList objects that are case insensitive. Use by calling CreateCaseInsensitiveHashtable or CreateCaseInsensitiveSortedList.

For .Net 1.0 (I am not sure if 1.0 supports StringComparer)

public class InsensitiveComparer : IEqualityComparer
{
    CaseInsensitiveComparer _comparer = new CaseInsensitiveComparer();
    public int GetHashCode(object obj)
    {
        return obj.ToString().ToLowerInvariant().GetHashCode();
    }

    public new bool Equals(object x, object y)
    {
        if (_comparer.Compare(x, y) == 0)
        {
            return true;
        }

        else
       {
           return false;
       }
    }
}

Hashtable dehash = new Hashtable(new InsensitiveComparer());