将IDictionary键转换为小写(C#)

时间:2020-03-06 15:01:05  来源:igfitidea点击:

我有一个方法,将IDictionary作为参数。
现在,我想提供一种从此字典中检索值的方法,但该方法应不区分大小写。

因此,我现在的解决方案是拥有一个静态函数,该函数循环遍历这些键并将它们转换为Lower(),如下所示:

private static IDictionary<ILanguage, IDictionary<string, string>> ConvertKeysToLowerCase(
    IDictionary<ILanguage, IDictionary<string, string>> dictionaries)
{
    IDictionary<ILanguage, IDictionary<string, string>> resultingConvertedDictionaries 
        = new Dictionary<ILanguage, IDictionary<string, string>>();
    foreach(ILanguage keyLanguage in dictionaries.Keys)
    {
        IDictionary<string, string> convertedDictionatry = new Dictionary<string, string>();
        foreach(string key in dictionaries[keyLanguage].Keys)
        {
            convertedDictionatry.Add(key.ToLower(), dictionaries[keyLanguage][key]);
        }
        resultingConvertedDictionaries.Add(keyLanguage, convertedDictionatry);
    }
    return resultingConvertedDictionaries;
}

现在,这可以,但仍然是相当大的代码块,与我的"干净而高效"的思想相矛盾。我们是否知道其他替代方法,以使字典的.ContainsKey()方法不会区分大小写?

解决方案

是的,通过Dictionary构造函数StringComparer.OrdinalIgnoreCase(或者另一个忽略大小写的比较器,具体取决于我们对文化的敏感性需求)。

乔恩

我们可以使用var关键字来消除一些混乱。从技术上讲,来源保持不变。另外,我只是传递并返回Dictionary <string,string>,因为我们没有对该ILanguage参数做任何事情,并使该方法更可重用:

private static IDictionary<string, string> ConvertKeysToLowerCase(
    IDictionary<string, string> dictionaries)
{
    var convertedDictionatry = new Dictionary<string, string>();
    foreach(string key in dictionaries.Keys)
    {
        convertedDictionatry.Add(key.ToLower(), dictionaries[key]);
    }
    return convertedDictionatry;
}

...并这样称呼:

// myLanguageDictionaries is of type IDictionary<ILanguage, IDictionary<string, string>>
foreach (var dictionary in myLanguageDictionaries.Keys)
{
  myLanguageDictionaries[dictionary].Value = 
      ConvertKeysToLowerCase(myLanguageDictionaries[dictionary].Value);
}

我们可以自己从IDictionary继承,而只是将对内部Dictionary实例的调用编组。

Add(string key, string value) { dictionary.Add(key.ToLowerInvariant(), value) ; }
public string this[string key]
{
    get { return dictionary[key.ToLowerInvariant()]; }
    set { dictionary[key.ToLowerInvariant()] = value; }
}
// And so forth.

LINQ版本使用IEnumerable &lt;T>扩展方法:

private static IDictionary<ILanguage, IDictionary<string, string>> ConvertKeysToLowerCase(
            IDictionary<ILanguage, IDictionary<string, string>> dictionaries)
        {
            return dictionaries.ToDictionary(
                x => x.Key, v => CloneWithComparer(v.Value, StringComparer.OrdinalIgnoreCase));
        }

        static IDictionary<K, V> CloneWithComparer<K,V>(IDictionary<K, V> original, IEqualityComparer<K> comparer)
        {
            return original.ToDictionary(x => x.Key, x => x.Value, comparer);
        }

System.Collections.Specialized.StringDictionary()可能会有所帮助。 MSDN指出:

"密钥以不区分大小写的方式处理;在与字符串字典一起使用之前,将其转换为小写。

在.NET Framework 1.0版中,此类使用区分区域性的字符串比较。但是,在.NET Framework 1.1版和更高版本中,此类在比较字符串时使用CultureInfo.InvariantCulture。有关区域性如何影响比较和排序的更多信息,请参见针对特定区域性对数据进行比较和排序以及执行对区域性不敏感的字符串操作。"

通过使用StringDictionary,可在创建时将键转换为小写。

http://simiansoftware.blogspot.com/2008/11/have-const-string-with-ui-description.html