Case insensitive dictionary with char key in C #

If I have Dictionary<char,...>

, is it possible to make the ContainsKey method case insensitive?

I know that Dictionary<string,...>

StringComparer.InvariantCultureIgnoreCase is used, but what if the key in the dictionary is char -type?

+3


source to share


6 answers


The Dictionary class has a constructor that accepts any IEqualityComparer

. What you need to do is implement a simple case insensitive IEqualityComparer<char>

and pass it to the constructor and it will be used when evaluating the key.

This is a similar question for a IComparer<char>

case-insensitive implementation . IEqualityComparer

will be almost identical:



+11


source


You can implement your own comparator:

public class CharComparer : IEqualityComparer<char>
{
     public bool Equals(char c1, char c2)
     {
          return char.ToLowerInvariant(c1) == char.ToLowerInvariant(c2);
     }
     public int GetHashCode(char c1)
     {
          return char.ToLowerInvariant(c1).GetHashCode();
     }

}

      



And pass it to the constructor:

var dict = new Dictioanry<char, object>(new CharComparer());

      

+7


source


You can also implement an extension method:

public static bool ContainsKeyInsensitive(this Dictionary<char, ...> dict, char c)
{      
  return dict.ContainsKey(char.ToUpper(c)) || dict.ContainsKey(char.ToLower(c));
}

      

+2


source


You can also call it twice.

if (dict.ContainsKey(char.ToLowerInvariant(ch)) || dict.ContainsKey(char.ToUpperInvariant(ch)))
{
    ...
}

      

As an extension method, this becomes:

public static bool ContainsKeyInsensitive<T>(this Dictionary<char, T> dict, char ch)
{
    return dict.ContainsKey(char.ToLowerInvariant(ch)) || dictionary.ContainsKey(char.ToUpperInvariant(ch));
}

      

+1


source


First; I know the accepted answer works and this is a good answer. However, I found out that no extension method / additional logic needs to be implemented to achieve the desired result.

I am assuming that you are using a dictionary because you want to map a key to a specific value - what they are for. If you only use it to find keys, you should use HashSet<char>

.

Well, having said that, let's take a look at the three options you have char

:;

  • You are ready to match uppercase , but as lowercase by specifying a different value in upper and lowercase.
  • Are you ready to show only in the lower register, that is, in upper case has the same meaning as in the upper register.
  • You are ready to display only in uppercase, which means that lowercase letters have the same meaning as uppercase.

I'll explain all three to them. For all the options, consider if the input is uppercase or lowercase char.

Option 1; Different keys, different meanings.

Displaying both ways is the way to go. If you need a different value for 'a'

and 'a'

, you need to add them anyway. So you can just use .ContainsKey()

and it will return the desired result. This option probably doesn't suit your needs as you are looking for a case insensitive dictionary.

Option 2: Lower case has the same meaning as upper case.

If you want to get the lowercase value at any time, just call .ContainsKey(yourChar.ToLower())

.

Option 3: Upper case has the same meaning as lower case.

The same story! Only now use .ContainsKey(yourChar.ToUpper())

it to get the right results. Since you pointed out in your comment that your dictionary only has top characters, this should be the way to go.

The same goes for case insensitivity Dictionary<string,T>

; just use only lowercase or uppercase (lowercase is my preference, but that's your own choice).

The following code snippet should demonstrate how it works.

Dictionary<char, object> dic = new Dictionary<char, object>();

public object GetIfKeyExists(char c)
{
    // Consider c = 'a' or c = 'A'

    // Option 1: Both have different values, so they should be existing anyway.
    if (dic.ContainsKey(c)) return dic[c];

    // Option 2: Only lowercase is mapped.
    char correctInput = c.ToLower();
    if (dic.ContainsKey(correctInput)) return dic[correctInput];

    // Option 3: Only uppercase is mapped.
    char correctInput = c.ToUpper();
    if (dic.ContainsKey(correctInput)) return dic[correctInput];
}

      

Then finally I still wonder why you should check the top or bottom. What information does it give if it returns true? You still don't know what exactly exists and why you should choose either uppercase or lowercase and stick with it.

0


source


just define the dictionary like this:

Dictionary<string, int> Dict = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);

      

0


source







All Articles