9

How to ignore case in dictionary keys? I'm doing this:

var map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
map.Add("e", "Letter e lower case");

string value = null;
if (!map.TryGetValue("E", out value)) {
    Console.WriteLine("Not found");
}

And I already tried to use StringComparer.InvariantIgnoreCase, and the result is the same. It cannot find the letter "E" in uppercase.

EDIT: Could I'm having some kind of culture conflicts with my environment settings even using OrdinalIgnoreCase ?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Luciano
  • 2,695
  • 6
  • 38
  • 53
  • 4
    Your code works as expected for me, the value for `"E"` *is* found. – svick Sep 18 '12 at 23:33
  • What is the output of the code? – NominSim Sep 18 '12 at 23:37
  • In my machine it didn´t work, the key isn´t found. Am i having culture issues ? But OrdinalIgnoreCase isn't the correct configureation to ignore side effects of environment culture. My OS is US_eng but all culture settings is Brazilian Portuguese. – Luciano Sep 19 '12 at 22:04
  • @Cuong Le: About your edit, I have reasons to prototype the returning type of Dictionary() instead of use var, and this was my snippet removed from a certain context when it's desirable. But ok, it can leave the sample small to be viewed here. – Luciano Sep 19 '12 at 22:10
  • 1
    Possible duplicate of [Case-INsensitive Dictionary with string key-type in C#](http://stackoverflow.com/questions/13988643/case-insensitive-dictionary-with-string-key-type-in-c-sharp) – Michael Freidgeim May 12 '16 at 07:26

3 Answers3

5

I tested it in others machines that I have (4 VMs, and 1 real) and discovered that only in my current VM (Win7 x64, us_eng, some portuguese settings, .net 4.5) the problem occurs. In my real machine and others VMs the test works fine, using OrdinalIgnoreCase as well InvariantIgnoreCase.

So, I guess that something very weird is in that environment, but I cannot spend time now to investigate it.

Unfortunately the question was flagged as useless by some guys, which demotivates my interesting to investigate it deeply.

Luciano
  • 2,695
  • 6
  • 38
  • 53
5

StringComparer.OrdinalIgnoreCase uses an internal call to Window API "nativeCompareOrdinalIgnoreCase" function in System.Globalization.TextInfo; so it is not Invariant Culture. Too bad the function in mscorlib.dll is internal, we can not test it out.

Anyhow, you should use StringComparer.InvariantCultureIgnoreCase instead of the former.

In case it still refuses to work, you can re-implement the IEqualityComparer

public class StringComparerIgnoreCase : IEqualityComparer<string>
{
    public bool Equals(string x, string y)
    {
        if (x != null && y != null)
        {
            return x.ToLowerInvariant() == y.ToLowerInvariant();
        }
        return false;
    }

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

Usage:

var map = new Dictionary<string, string>(new StringComparerIgnoreCase());
slolife
  • 19,520
  • 20
  • 78
  • 121
Hiệp Lê
  • 636
  • 4
  • 8
0

You are correct with the declaration for Dictionary for case-insensitive dictionary keys.

You can also use map.ContainsKey("E") and map["E"] to search for a key and to access it.

Gerhard Powell
  • 5,965
  • 5
  • 48
  • 59