我有System.Collections.Generic.Dictionary<A, B> dict
,其中A和B是类,实例A a
(其中dict.ContainsKey(a)
为真)。
是否可以直接从字典中获取包含a
的KeyValuePair?
或者我是否需要创建一个新的KeyValuePair:new KeyValuePair<A, B>(a, dict[a])
?
答案 0 :(得分:38)
你需要创建一个新的KeyValuePair
1 - 但请记住,KVP是一种值类型(结构),所以它不像你引入一个新的低效率通过做这个。任何返回KVP的方法都会创建一个副本 - 你只是直接创建实例。
如果您愿意,可以随时向IDictionary<TKey, TValue>
添加扩展方法:
public static KeyValuePair<TKey, TValue> GetEntry<TKey, TValue>
(this IDictionary<TKey, TValue> dictionary,
TKey key)
{
return new KeyValuePair<TKey, TValue>(key, dictionary[key]);
}
正如评论中所指出的那样,存储在字典中的密钥完全有可能与提供的密钥不是相同,只是在语义上相同 - 通过某些语义可以由{ {1}}(例如,与不区分大小写的字典一样。)在这种情况下,上面的代码不会返回字典中的实际条目,而是返回您提供的用于查找的键的条目。不幸的是,没有找到原始密钥的有效方法 - 你必须遍历字典:(
1 我知道你可以迭代字典条目并找到相应的条目,但我没有理由为什么你想要这样做一个非常好的索引器,它是O(1)而不是O(N)。
答案 1 :(得分:16)
当Dictionary<TKey, TValue>
实现IEnumerable<KeyValuePair<TKey, TValue>>
时,您可以使用linq:
var pair = _dictionary.SingleOrDefault(p => p.Key == myKey);
答案 2 :(得分:1)
我们无法以"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));
}
答案 3 :(得分:0)
对我来说myDict.AsEnumerable
做到了......
答案 4 :(得分:0)
接受的答案可能对某些常见情况没有太大帮助。请记住,关键是一个类。因此,为了访问该键的值对象,必须已经存在一个键对象。那么,如果您有一个较旧的键对象并且字典在该键对象中包含较新的信息(但仍使用该键对象中的相同键字段)怎么办?或者,另一种非常合理的情况是,如果只有用作键的字段可用,然后创建一个包含这些键字段的临时键对象会怎样?
接受的答案使用扩展方法返回包含旧键的 KeyValuePair
,而不是字典中的实际键对象。因此,它不适用于这些常见情况。
因此,Supercat 对包含键的值使用 KeyValuePair
的想法是唯一可以在 O(1) 时间内工作的方法。缺点是这种方法不仅更复杂,而且对于字典中的每个条目还需要额外的 8 个字节(对于 64 位操作系统),这通常不是问题。看起来微软错过了这个机会,因为他们真的应该提供一种返回字典中键的方法。
以下是如何创建以 KeyValuePair
作为值的字典的示例:
var dict = new Dictionary<a, KeyValuePair<a, b>>();
然后访问它:
var kvp = dict[key]; // key is of type a.
a itemKey = kvp.key;
b itemVal = kvp.value;
因此,如果您可以控制字典定义,这样的代码将起作用。如果您使用的是 3rd 方软件,或者更改太麻烦,那么您必须遍历整个集合 - 这是一个 O(n) 操作。