1

I have a case sensitive dictionary (very huge one). I want to search the keys of this dictionary using ignore-case (case-insensitive). I don't want to use foreach to iterate throughout this dictionary and compare each values as the dictionary contains too many data.

Is there a better (most-efficient) way to to do this using C#? I want some suggestions.

Ravi Raj
  • 66
  • 7
  • 1
    Would you consider a linq query with string.Compare("a", "A",StringComparison.CurrentCultureIgnoreCase) to be a "loop"? – Andrew Grothe Jun 29 '12 at 12:02

2 Answers2

4

So if I understand it correctly you want a dictionary that holds strings as they are, but hashes in a case-insensitive manner, such that you can still search in O(1) amortized time regardless of case?

The way I see it you need to pass a custom IEqualityComparer when creating the Dictionary with this constructor and when implementing the IEqualityComparer treat strings as if they are all upper or lower case for example and the same for the hash code (i.e. return the hash code of the string turned to upper case).

For example:

class MyComparer : IEqualityComparer<string>
{
    public bool Equals(string x, string y)
    {
        return x.ToUpper() == y.ToUpper();
    }

    public int GetHashCode(string obj)
    {
        return obj.ToUpper().GetHashCode();
    }
}

...

Dictionary<String, String> dict = new Dictionary<string, string>(new MyComparer());

Now practically your dictionary holds the strings normally but when searching or adding it treats them as if they are all uppercase so "AbcD" is treated the same as "aBCd" (both as "ABCD").

Tudor
  • 61,523
  • 12
  • 102
  • 142
  • that however would turn the case-sensitive dictionary into a case-insensitive one – Rune FS Jun 29 '12 at 12:07
  • @Rune FS: For hashing yes, because otherwise you would not be able to do searches in a case-insensitive manner. But the strings themselves would still be kept with their original characters. At least this is what I understood that he wants. – Tudor Jun 29 '12 at 12:09
  • See the notes on string comparisons here http://stackoverflow.com/questions/9033/hidden-features-of-c/12137#12137 and here http://stackoverflow.com/questions/2801508/what-is-wrong-with-tolowerinvariant – Greg B Jun 29 '12 at 12:10
2

Tudor's answers was a good one and I'd like to complement it by recommanding you to use the StringComparer.CurrentCultureIgnoreCase instead of creating your own comparer class (especialy if the expected result is the same).

Example :

Dictionary<string, string> openWith = 
                  new Dictionary<string, string>( 
                      StringComparer.CurrentCultureIgnoreCase);

Source : http://msdn.microsoft.com/en-us/library/ms132072.aspx

Drahakar
  • 5,986
  • 6
  • 43
  • 58