通用字典不区分大小写 [英] Case insensitive access for generic dictionary
问题描述
字典< string,int> MyDictionary;
该字典包含大写和小写的键。
另一方面,我得到一个潜在的键(字符串)的列表,但是我无法保证。我试图使用键获取字典中的值。但是当然,以下将会失败,因为我有一个不匹配的情况:
bool Success = MyDictionary.TryGetValue(MyIndex,out TheValue) ;
我希望TryGetValue会有一个忽略大小写标志,如 MSDN文档,但似乎这对于通用字典无效。
有没有办法获取该字典的值忽略密钥大小写?
是否有更好的解决方法,而不是使用适当的<?> StringComparer.OrdinalIgnoreCase 参数创建新的字典副本?
在尝试获取值时,无法指定 StringComparer
。如果你考虑过,那么Foo.GetHashCode()
和foo.GetHashCode()
完全不同所以没有合理的方法可以在区分大小写的哈希映射上实现不区分大小写的get。
然而,您可以在第一个中创建一个不区分大小写的字典地方使用: -
var caseInsensitiveDictionary =
new Dictionary< string,int>(StringComparer.OrdinalIgnoreCase);
或者创建一个新的不区分大小写的字典与现有的区分大小写字典的内容(如果你确定没有案件冲突): -
var oldDictionary = ...;
var newDictionary =
new Dictionary< string,int>(oldDictionary,StringComparer.OrdinalIgnoreCase);
此字典然后使用 GetHashCode()
执行 StringComparer.OrdinalIgnoreCase
,使 comparer.GetHashCode(Foo)
和比较器。 GetHashcode(foo)
给你相同的值。
另外,如果字典中只有几个元素,和/或您只需要查找一次或两次,您可以将原始字典视为 IEnumerable< KeyValuePair< K,T>
,然后重复: -
var myKey = ...;
var myDictionary = ...;
var value =
myDictionary.FirstOrDefault(
x => String.Equals(x.Key,
myKey,
StringComparison.OrdinalIgnoreCase))?
或者如果你愿意,没有LINQ: -
var myKey = ...;
var myDictionary = ...;
int?值;
foreach(myDictionary中的var元素)
{
if(String.Equals(element.Key,myKey,StringComparison.IgnoreOrdinalCase))
{
value = element。值;
break;
}
}
这样可以节省创建新数据结构的费用,但作为回报,查找的成本是O(n)而不是O(1)。
I have an application that use managed dlls. One of those dlls return a generic dictionary:
Dictionary<string, int> MyDictionary;
The dictionary contains keys with upper and lower case.
On another side I am getting a list of potential keys (string) however I cannot guarantee the case. I am trying to get the value in the dictionary using the keys. But of course the following will fail since I have a case mismatch:
bool Success = MyDictionary.TryGetValue( MyIndex, out TheValue );
I was hoping the TryGetValue would have an ignore case flag like mentioned in the MSDN doc, but it seems this is not valid for generic dictionaries.
Is there a way to get the value of that dictionary ignoring the key case? Is there a better workaround than creating a new copy of the dictionary with the proper StringComparer.OrdinalIgnoreCase parameter?
There's no way to specify a StringComparer
at the point where you try to get a value. If you think about it, "Foo".GetHashCode()
and "foo".GetHashCode()
are totally different so there's no reasonable way you could implement a case-insensitive get on a case-sensitive hash map.
You can, however, create a case-insensitive dictionary in the first place using:-
var caseInsensitiveDictionary =
new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
Or create a new case-insensitive dictionary with the contents of an existing case-sensitive dictionary (if you're sure there are no case collisions):-
var oldDictionary = ...;
var newDictionary =
new Dictionary<string, int>(oldDictionary, StringComparer.OrdinalIgnoreCase);
This dictionary then uses the GetHashCode()
implementation on StringComparer.OrdinalIgnoreCase
such that comparer.GetHashCode("Foo")
and comparer.GetHashcode("foo")
give you the same value.
Alternately, if there are only a few elements in the dictionary, and/or you only need to lookup once or twice, you can treat the original dictionary as an IEnumerable<KeyValuePair<K,T>>
and just iterate over it:-
var myKey = ...;
var myDictionary = ...;
var value =
myDictionary.FirstOrDefault(
x => String.Equals(x.Key,
myKey,
StringComparison.OrdinalIgnoreCase))?.Value;
Or if you prefer, without the LINQ:-
var myKey = ...;
var myDictionary = ...;
int? value;
foreach (var element in myDictionary)
{
if (String.Equals(element.Key, myKey, StringComparison.IgnoreOrdinalCase))
{
value = element.Value;
break;
}
}
This saves you the cost of creating a new data structure, but in return the cost of a lookup is O(n) instead of O(1).
这篇关于通用字典不区分大小写的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!