直接从 Dictionary<> 获取 KeyValuePair<>
-
06-07-2019 - |
题
我有 System.Collections.Generic.Dictionary<A, B> dict
其中 A 和 B 是类,以及一个实例 A a
(在哪里 dict.ContainsKey(a)
是真的)。
是否可以获取包含的KeyValuePair a
直接从字典里取?
或者我是否需要创建一个新的 KeyValuePair: new KeyValuePair<A, B>(a, dict[a])
?
解决方案
你需要创建一个新的 KeyValuePair
1 - 但请记住KVP是一种值类型(结构),所以它不像你介绍的那样这样做会带来新的低效率。任何返回KVP的方法都会创建一个副本 - 你只是直接创建实例。
如果您愿意,可以随时向 IDictionary&lt; TKey,TValue&gt;
添加扩展方法:
public static KeyValuePair<TKey, TValue> GetEntry<TKey, TValue>
(this IDictionary<TKey, TValue> dictionary,
TKey key)
{
return new KeyValuePair<TKey, TValue>(key, dictionary[key]);
}
正如评论中所指出的,存储在字典中的密钥完全有可能不是与提供的密钥相同的相同,只是在语义上相同 - 通过某些语义可以通过<代码> IEqualityComparer (例如,与不区分大小写的字典一样。)在这种情况下,上面的代码不会返回字典中的实际条目,而是返回您提供的用于查找的键的条目。不幸的是,没有找到原始密钥的有效方法 - 你必须遍历字典:(
1 我知道你可以迭代字典条目并找到相应的条目,但我没有理由为什么你曾经想要这样做一个非常好的索引器,它是O(1)而不是O(N)。
其他提示
当 Dictionary&lt; TKey,TValue&gt;
实现 IEnumerable&lt; KeyValuePair&lt; TKey,TValue&gt;&gt;
时,你可以使用linq:
var pair = _dictionary.SingleOrDefault(p => p.Key == myKey);
我们无法到达 "IPHone"
这边走:
var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ "IPHone", "TCP/IP honing tools" }
};
Console.WriteLine(dict["iPhone"]); // "TCP/IP honing tools"
Console.WriteLine( ??? ); // "IPHone"
当前 API 似乎没有 O(1) 解决方案,但循环遍历所有条目是可行的:
var keyValue = dict.First(p => dict.Comparer.Equals(p.Key, "iPhone"));
Console.WriteLine(keyValue.Key); // "IPHone"
Console.WriteLine(keyValue.Value); // "TCP/IP honing tools"
或者作为懒人的扩展:
[Pure]
public static KeyValuePair<TKey, TValue> GetEntry<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key)
{
var comparer = dictionary.Comparer;
return dictionary.FirstOrDefault(p => comparer.Equals(p.Key, key));
}
对我来说 myDict.AsEnumerable
做到了......