C#中字符串键类型不区分大小写的字典


155

如果我有一个Dictionary<String,...>可能使像ContainsKey不区分大小写的方法?

这似乎有关,但我不太了解:c#字典:通过声明使Key不区分大小写


5
使用有什么问题StringComparer.InvariantCultureIgnoreCase?它按照它所说的
去做

5
我从来没有听说过,所以这个问题!
男孩先生2012年


这个问题是相关的,但并非完全相同。那就是如何处理现有词典的内容。我从新代码开始,因此这里的答案更合适。
goodeye

Answers:


321

这似乎有关,但我不太了解:c#字典:通过声明使Key不区分大小写

确实是有关的。解决方案是告诉字典实例不要使用标准的字符串比较方法(区分大小写),而要使用不区分大小写的方法。这是使用适当的构造函数完成的:

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

构造函数希望使用IEqualityComparer,它会告诉字典如何比较键。

StringComparer.InvariantCultureIgnoreCase给您一个IEqualityComparer实例,该实例以不区分大小写的方式比较字符串。


1
完美,我以某种方式错过了类似STL的将比较器传递到ctor的方法。
男孩先生2012年

7
它永远不会令我惊讶,我总是如何在这里找到任何编码问题的答案!也许我会以你的名字命名我的下一只猫,康拉德!:-)
Jamie

10
可能,StringComparison.OrdinalIgnoreCase比较器的速度比基于文化的速度更快:stackoverflow.com/questions/492799/…–
Manushin Igor

如果我没有创建字典,而是尝试使用ContainsKey()在作为对象一部分的现有字典上进行不区分大小写的键匹配,该怎么办?
Shridhar R Kulkarni

1
@ShridharRKulkarni从根本上讲,您不能(有效)。比较逻辑是内部字典数据结构的核心部分。为此,容器必须为其数据维​​护多个索引,而字典则不这样做。
Konrad Rudolph

21
var myDic = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
myDic.Add("HeLlo", "hi");

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

1
代码段说明了一切。很有帮助。不知道为什么该帖子的投票数比被接受的答案晚3分钟才这么少。
RBT

14

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

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


3
这很好。不过请注意,如果更改Any为不存在,SingleOrDefault则不会找null回来,而是会得到一个键值对,并且键和值都设置为null
NibblyPig

1
Contains似乎对于您当时正在研究的东西来说是一个非常特定的用例。作为更通用的有用答案,我认为Equals更好。并在同一条注释上,与其使用来复制字符串ToLower(),不如使用StringComparison.xxxCase
Suamere

1
这非常有用,摆脱ToLower绝对是一个改进-我的用例是:返回AppliedBuffs.Any(b => b.Key.Equals(Name,StringComparison.OrdinalIgnoreCase)); 完美的不区分大小写的包含在区分大小写的字典中。
大卫·伯福德

我很想拒绝这个。提醒您,如果您是字典的所有者,那肯定不是这样做的方式。仅当您不知道字典的实例化方式时,才使用此方法。即使这样,对于字符串的精确匹配(而不仅仅是部分匹配),也可以使用dict.Keys.Contains("bla", appropriate comparer)LINQ重载来简化使用。
nawfal

1

我遇到了同样的麻烦,需要在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!");

0

如果您在实例创建过程中没有控制权,可以说您的对象已从json等中删除,则可以创建一个从字典类继承的包装器类。

public class CaseInSensitiveDictionary<TValue> : Dictionary<string, TValue>
{
    public CaseInSensitiveDictionary() : base(StringComparer.OrdinalIgnoreCase){}
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.