繁体   English   中英

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

[英]Case Insensitive Dictionary with char key in C#

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

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

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

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

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

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

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

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

你也可以叫它两次。

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

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

我想你正在使用字典,因为你想将一个键映射到一个特定的值 - 这正是它们的用途。 如果仅使用它来查找键,则应使用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,它会给出什么信息? 你仍然不知道究竟存在哪一个 - 这就是为什么你应该选择映射大写或小写并坚持下去。

只需像这样定义字典:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM