通用字典的不区分大小写访问 [英] Case insensitive access for generic dictionary

查看:25
本文介绍了通用字典的不区分大小写访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用托管 dll 的应用程序.其中一个 dll 返回一个通用字典:

I have an application that use managed dlls. One of those dlls return a generic dictionary:

Dictionary<string, int> MyDictionary;  

字典包含大小写的键.

另一方面,我得到了一个潜在键(字符串)列表,但我不能保证这种情况.我正在尝试使用键获取字典中的值.但当然以下会失败,因为我有一个案例不匹配:

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 );  

我希望 TryGetValue 有一个 忽略大小写 标志,就像 MSDN 文档,但似乎这对通用词典无效.

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.

有没有办法在忽略关键案例的情况下获取该字典的值?有没有比使用正确的 StringComparer.OrdinalIgnoreCase 参数创建字典的新副本更好的解决方法?

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?

推荐答案

无法在您尝试获取值的地方指定 StringComparer.如果你仔细想想,"foo".GetHashCode()"FOO".GetHashCode() 是完全不同的,所以没有合理的方法可以实现不区分大小写的获取区分大小写的哈希映射.

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 comparer = StringComparer.OrdinalIgnoreCase;
var caseInsensitiveDictionary = new Dictionary<string, int>(comparer);

或者用现有的区分大小写的字典的内容创建一个新的不区分大小写的字典(如果你确定没有大小写冲突):-

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 comparer = StringComparer.OrdinalIgnoreCase;
var newDictionary = new Dictionary<string, int>(oldDictionary, comparer);

这个新字典然后使用 StringComparer.OrdinalIgnoreCase 上的 GetHashCode() 实现,所以 comparer.GetHashCode("foo")comparer.GetHashcode("FOO") 给你相同的值.

This new dictionary then uses the GetHashCode() implementation on StringComparer.OrdinalIgnoreCase so comparer.GetHashCode("foo") and comparer.GetHashcode("FOO") give you the same value.

或者,如果字典中只有几个元素,和/或您只需要查找一两次,则可以将原始字典视为IEnumerable> 并对其进行迭代:-

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<TKey, TValue>> and just iterate over it:-

var myKey = ...;
var myDictionary = ...;
var comparer = StringComparer.OrdinalIgnoreCase;
var value = myDictionary.FirstOrDefault(x => String.Equals(x.Key, myKey, comparer)).Value;

或者,如果您愿意,也可以不使用 LINQ:-

Or if you prefer, without the LINQ:-

var myKey = ...;
var myDictionary = ...;
var comparer = StringComparer.OrdinalIgnoreCase;
int? value;
foreach (var element in myDictionary)
{
  if (String.Equals(element.Key, myKey, comparer))
  {
    value = element.Value;
    break;
  }
}

这为您节省了创建新数据结构的成本,但作为回报,查找的成本是 O(n) 而不是 O(1).

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆