I've got a Method that gets a IDictionary as a parameter. Now I want to provide a method that retrieves the value from this dictionary, but it should be case-invariant.
我有一个获取IDictionary作为参数的方法。现在我想提供一个从这个字典中检索值的方法,但它应该是case-invariant。
So my solution to this right now was to have a static function that loops through the keys and converts them toLower() like this:
所以我现在解决这个问题的方法是让一个静态函数循环遍历键并将它们转换为下面的函数(如下所示):
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;
}
Now, this is ok, but still it's a pretty huge chunk of code that contradicts my idea of "clean and efficient". Do you know any alternatives to this so that the .ContainsKey() method of the dictionary doesn't differentiate between casing?
现在,这没关系,但它仍然是一大堆代码,与我的“干净和高效”的想法相矛盾。你知道任何替代方法,以便字典的.ContainsKey()方法不区分套管吗?
6 个解决方案
#1
29
Yes - pass the Dictionary constructor StringComparer.OrdinalIgnoreCase
(or another case-ignoring comparer, depending on your culture-sensitivity needs).
是 - 传递Dictionary构造函数StringComparer.OrdinalIgnoreCase(或另一个忽略大小写的比较器,具体取决于您的文化敏感性需求)。
Jon
#2
2
By using a StringDictionary the keys are converted to lower case at creating time.
通过使用StringDictionary,键在创建时转换为小写。
http://simiansoftware.blogspot.com/2008/11/have-const-string-with-ui-description.html
#3
1
You could use the var keyword to remove some clutter. Technically the source remains the same. Also I would just pass and return a Dictionary<string, string> because you're not doing anything with that ILanguage parameter and make the method more reusable:
您可以使用var关键字删除一些混乱。从技术上讲,来源保持不变。此外,我只是传递并返回一个Dictionary
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;
}
... and call it like so:
......并像这样称呼它:
// myLanguageDictionaries is of type IDictionary<ILanguage, IDictionary<string, string>>
foreach (var dictionary in myLanguageDictionaries.Keys)
{
myLanguageDictionaries[dictionary].Value =
ConvertKeysToLowerCase(myLanguageDictionaries[dictionary].Value);
}
#4
1
You could inherit from IDictionary yourself, and simply marshal calls to an internal Dictionary instance.
您可以自己继承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.
#5
1
System.Collections.Specialized.StringDictionary() may help. MSDN states:
System.Collections.Specialized.StringDictionary()可能有所帮助。 MSDN声明:
"The key is handled in a case-insensitive manner; it is translated to lowercase before it is used with the string dictionary.
“密钥以不区分大小写的方式处理;在与字典字典一起使用之前,它被翻译为小写。
In .NET Framework version 1.0, this class uses culture-sensitive string comparisons. However, in .NET Framework version 1.1 and later, this class uses CultureInfo.InvariantCulture when comparing strings. For more information about how culture affects comparisons and sorting, see Comparing and Sorting Data for a Specific Culture and Performing Culture-Insensitive String Operations."
在.NET Framework 1.0版中,此类使用区分文化的字符串比较。但是,在.NET Framework 1.1及更高版本中,此类在比较字符串时使用CultureInfo.InvariantCulture。有关文化如何影响比较和排序的更多信息,请参阅比较和排序特定文化的数据和执行不区分文化的字符串操作。“
#6
-1
LINQ version using the IEnumerable<T>
extension methods:
LINQ版本使用IEnumerable
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);
}
#1
29
Yes - pass the Dictionary constructor StringComparer.OrdinalIgnoreCase
(or another case-ignoring comparer, depending on your culture-sensitivity needs).
是 - 传递Dictionary构造函数StringComparer.OrdinalIgnoreCase(或另一个忽略大小写的比较器,具体取决于您的文化敏感性需求)。
Jon
#2
2
By using a StringDictionary the keys are converted to lower case at creating time.
通过使用StringDictionary,键在创建时转换为小写。
http://simiansoftware.blogspot.com/2008/11/have-const-string-with-ui-description.html
#3
1
You could use the var keyword to remove some clutter. Technically the source remains the same. Also I would just pass and return a Dictionary<string, string> because you're not doing anything with that ILanguage parameter and make the method more reusable:
您可以使用var关键字删除一些混乱。从技术上讲,来源保持不变。此外,我只是传递并返回一个Dictionary
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;
}
... and call it like so:
......并像这样称呼它:
// myLanguageDictionaries is of type IDictionary<ILanguage, IDictionary<string, string>>
foreach (var dictionary in myLanguageDictionaries.Keys)
{
myLanguageDictionaries[dictionary].Value =
ConvertKeysToLowerCase(myLanguageDictionaries[dictionary].Value);
}
#4
1
You could inherit from IDictionary yourself, and simply marshal calls to an internal Dictionary instance.
您可以自己继承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.
#5
1
System.Collections.Specialized.StringDictionary() may help. MSDN states:
System.Collections.Specialized.StringDictionary()可能有所帮助。 MSDN声明:
"The key is handled in a case-insensitive manner; it is translated to lowercase before it is used with the string dictionary.
“密钥以不区分大小写的方式处理;在与字典字典一起使用之前,它被翻译为小写。
In .NET Framework version 1.0, this class uses culture-sensitive string comparisons. However, in .NET Framework version 1.1 and later, this class uses CultureInfo.InvariantCulture when comparing strings. For more information about how culture affects comparisons and sorting, see Comparing and Sorting Data for a Specific Culture and Performing Culture-Insensitive String Operations."
在.NET Framework 1.0版中,此类使用区分文化的字符串比较。但是,在.NET Framework 1.1及更高版本中,此类在比较字符串时使用CultureInfo.InvariantCulture。有关文化如何影响比较和排序的更多信息,请参阅比较和排序特定文化的数据和执行不区分文化的字符串操作。“
#6
-1
LINQ version using the IEnumerable<T>
extension methods:
LINQ版本使用IEnumerable
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);
}