我有一个案例敏感字典,
Dictionary<string, uint> itemNames = new Dictionary<string, uint>(StringComparer.Ordinal);
所以我可以在这本词典中使用区分大小写的键。
例如,我可以拥有以下键值对,
...
当有人传递密钥时,我想要检索该值。检索应该是部分不区分大小写的,这意味着,如果匹配的是精确的大小写,则返回区分大小写的结果,如果区分大小写的密钥不存在则检索不区分大小写的键值。
例如,将上述值插入字典
如果用户将密钥传递为&#34; TEST&#34;我需要返回20。
如果用户将密钥传递为&#34; TEST1&#34; ,找不到区分大小写的密钥,所以我需要返回30.
如何在C#中实现这一目标?
答案 0 :(得分:3)
您应首先使用TryGetValue
检查是否有项目。如果没有,请选择第一个匹配项:
string key = "test1";
int val;
if (!itemNames.TryGetValue(key, out val))
{
val = itemNames.FirstOrDefault
(k => string.Equals(k.Key, key, StringComparison.OrdinalIgnoreCase)
)?.Value ?? 0;
}
请注意此代码的性能。如果你有一个大字典,第一次尝试有很多错过,第二个(不区分大小写)字典会更好。
答案 1 :(得分:0)
两个单独的词典:性能方面,获得O(1)
平均查找时间的唯一方法是使用两个词典,其中一个将使用默认比较器,另一个将使用默认比较器一个不区分大小写的。
两个单独的词典,第2部分:也许最正确的方法是:
// map each string to single item
Dictionary<string, int> CaseSensitive;
// map each string to multiple items, case insensitive
Dictionary<string, List<KeyValuePair<string, int>>> CaseInsensitive;
甚至
// map each string to single item
Dictionary<string, int> CaseSensitive;
// map each string to multiple items, case insensitive, with O(1) lookup time
Dictionary<string, HashSet<KeyValuePair<string, int>>> CaseInsensitive;
您的不区分大小写的搜索可以正确返回所有匹配项,而不仅仅是最近插入的匹配项。
“hacky”自定义相等比较器:或者,您可以使用单个字典但是欺骗了一点并制作了一个“特殊”比较器,它将为案例返回相同的哈希码 - 不敏感(因此也区分大小写)匹配,但根据标志更改其Equals
方法的工作方式。这会将test
和TEST
放在同一个存储桶中。
但这是我不会使用这些的唯一方法,因为比较器是可变的(乍一看可能不是很明显这是如何工作的,这是不寻常的),它可能会导致细微的错误(你总是需要记住在插入/删除之前将IsCaseSensitive
设置为true
,并且对于区分大小写的搜索可能性能稍差(因为更多项目将共享同一个存储区)。