在C#中使用char键的不区分大小写字典

时间:2014-12-18 08:33:39

标签: c# dictionary collections

如果我有Dictionary<char,...>,是否可以使方法ContainsKey不区分大小写?

我知道,在Dictionary<string,...>中使用了StringComparer.InvariantCultureIgnoreCase,但是当字典中的键是char-type时该怎么办?

6 个答案:

答案 0 :(得分:11)

Dictionary类有一个构造函数,可以接受任何IEqualityComparer。您需要做的是实现一个简单的不区分大小写的IEqualityComparer<char>并将其传递给构造函数,并在评估密钥时使用它。

这是一个类似的问题,用于在没有区分大小写的情况下实施IComparer<char>IEqualityComparer几乎完全相同:

答案 1 :(得分:7)

您可以实现自己的比较器:

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();
     }

}

并将其传递给构造函数:

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

答案 2 :(得分:2)

你可以实现一个扩展方法:

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

答案 3 :(得分:1)

你也可以打电话两次。

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

作为一种扩展方法,它变为:

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

答案 4 :(得分:0)

起初;我知道接受的答案是有效的,这是一个很好的答案。然而,我发现实现任何扩展方法/附加逻辑以实现所需结果不是必要的。

我想你正在使用字典,因为你想将一个键映射到一个特定的值 - 这正是它们的用途。如果仅使用它来查找键,则应使用HashSet<char>

好的,那就是说,让我们来看看char的三个选项;

  • 您愿意将大写以及映射为小写,同时为大写和小写提供不同的值。
  • 您愿意将映射小写,这意味着大写的与大写相同
  • 您愿意映射大写,这意味着小写的与大写相同

我将解释他们三个。对于所有选项,请考虑不知道输入字符是大写还是小写。

选项1;不同的键,不同的值。

映射两者是要走的路。如果您需要'a''A'的其他值,则无论如何都需要添加它们。因此,您只需使用.ContainsKey()即可返回所需的结果。此选项可能不适合您的需求,因为您正在寻找不区分大小写的字典。

选项2:小写与大写具有相同的值。

如果您想随时获得小写值,请致电.ContainsKey(yourChar.ToLower())

选项3:大写与小写具有相同的值。

同样的故事!只有现在,使用.ContainsKey(yourChar.ToUpper())来获得正确的结果。由于您在评论中发布了您的词典仅包含大写字母,因此应该采用这种方式。

同样适用于不区分大小写的Dictionary<string,T>;只是映射小写或大写(小写有我的偏好,但这是你自己的选择)。

以下代码段应演示其工作原理。

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];
}

然后,最后,我仍然想知道你为什么要检查上层更低。如果它返回true,它会给出什么信息?您仍然不知道哪个确切存在 - 这就是为什么您应该选择映射大写或小写并坚持下去。

答案 5 :(得分:0)

只需定义字典:

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