【问题标题】:Case-INsensitive Dictionary with string key-type in C#在 C# 中具有字符串键类型的不区分大小写字典
【发布时间】:2012-12-08 22:41:27
【问题描述】:

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

这似乎相关,但我没有正确理解它:c# Dictionary: making the Key case-insensitive through declarations

【问题讨论】:

  • 这个问题是相关的,但与这个问题并不完全重复。那一个进入如何处理现有的字典。我从新代码开始,所以这里的答案更适合。

标签: c# collections generic-collections


【解决方案1】:

这似乎相关,但我没有正确理解:c# Dictionary: making the Key case-insensitive through declarations

确实有关系。解决方案是告诉字典实例不要使用标准的字符串比较方法(区分大小写),而是使用不区分大小写的方法。这是使用appropriate constructor

var dict = new Dictionary<string, YourClass>(
        StringComparer.InvariantCultureIgnoreCase);

构造函数需要一个IEqualityComparer,它告诉字典如何比较键。

StringComparer.InvariantCultureIgnoreCase 为您提供IEqualityComparer 实例,它以不区分大小写的方式比较字符串。

【讨论】:

  • 可能,StringComparison.OrdinalIgnoreCase 比较器比基于文化的比较快:stackoverflow.com/questions/492799/…
  • @ShridharRKulkarni 你基本上不能(有效地)。比较逻辑是内部字典数据结构的核心部分。为此,容器必须为其数据维​​护多个索引,而字典不会这样做。
【解决方案2】:
var myDic = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
myDic.Add("HeLlo", "hi");

if (myDic.ContainsKey("hello"))
    Console.WriteLine(myDic["hello"]);

【讨论】:

    【解决方案3】:

    很少有机会处理从第三方或外部 dll 提取的字典。使用 linq

    YourDictionary.Any(i => i.KeyName.ToLower().Contains("yourstring")))
    

    【讨论】:

    • 这很好用。不过需要注意的是,如果您将Any 更改为SingleOrDefault,如果null 不存在,您将不会得到它,相反,您将获得一个键值对,键和值都设置为null!跨度>
    • Contains 似乎是您当时正在做的事情的一个非常具体的用例。作为一个更通用的有用答案,我认为Equals 更好。同样的,与其用ToLower()复制一个字符串,不如使用StringComparison.xxxCase
    • 我很想对此投反对票。请注意,如果您是字典的所有者,那么这肯定不是这样做的方法。如果您不知道字典是如何实例化的,请仅使用此方法。即使这样,对于字符串的精确匹配(不仅仅是部分匹配),使用dict.Keys.Contains("bla", appropriate comparer) LINQ 重载以方便使用。
    【解决方案4】:

    如果您无法控制实例的创建,假设您的对象已从 json 等中删除,您可以创建一个继承自字典类的包装类。

    public class CaseInSensitiveDictionary<TValue> : Dictionary<string, TValue>
    {
        public CaseInSensitiveDictionary() : base(StringComparer.OrdinalIgnoreCase){}
    }
    

    【讨论】:

    • 如何在保持 Dictionary 语法的情况下做到这一点?
    【解决方案5】:

    我刚刚遇到了同样的麻烦,我需要在 ASP.NET Core 控制器中使用不区分大小写的字典。

    我写了一个可以解决问题的扩展方法。 也许这对其他人也有帮助......

    public static IDictionary<string, TValue> ConvertToCaseInSensitive<TValue>(this IDictionary<string, TValue> dictionary)
    {
        var resultDictionary = new Dictionary<string, TValue>(StringComparer.InvariantCultureIgnoreCase);
        foreach (var (key, value) in dictionary)
        {
            resultDictionary.Add(key, value);
        }
    
        dictionary = resultDictionary;
        return dictionary;
    }
    

    使用扩展方法:

    myDictionary.ConvertToCaseInSensitive();
    

    然后从字典中获取一个值:

    myDictionary.ContainsKey("TheKeyWhichIsNotCaseSensitiveAnymore!");
    

    【讨论】:

      【解决方案6】:

      我知道这是一个较老的问题,但我遇到了同样的问题,即字典来自未在构造函数中实现忽略大小写 StringComparer 的第 3 方工具。从上面的 @Soviut 方法调整而来,但感觉这更干净,让您可以立即使用该值。

      var lookup = source.FirstOrDefault(x => x.Key.Equals("...", StringComparison.OrdinalIgnoreCase));
      if (lookup.Key != null)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-05
        • 1970-01-01
        • 2020-02-18
        相关资源
        最近更新 更多