Получение KeyValuePair <> непосредственно из Словаря <>
У меня есть System.Collections.Generic.Dictionary<A, B> dict
, где A и B - классы, а экземпляр A a
(где dict.ContainsKey(a)
- истина).
Можно ли получить ключ KeyValuePair, содержащий a
, непосредственно из Словаря?
Или мне нужно создать новый KeyValuePair: new KeyValuePair<A, B>(a, dict[a])
?
Ответы
Ответ 1
Вам нужно создать новый KeyValuePair
1 - но имейте в виду, что KVP - это тип значения (структура), так что вам не нравится, что вы вводите новую неэффективность, делая это. Любой метод, возвращающий KVP, будет создавать копию в любом случае - вы просто создаете экземпляр напрямую.
Вы всегда можете добавить метод расширения к IDictionary<TKey, TValue>
, если хотите:
public static KeyValuePair<TKey, TValue> GetEntry
(this IDictionary<TKey, TValue> dictionary,
TKey key)
{
return new KeyValuePair<TKey, TValue>(key, dictionary[key]);
}
Как отмечено в комментариях, вполне возможно, что ключ, который хранится в словаре, не совпадает с тем, который был предоставлен, просто семантически равен - некоторой семантикой, которую можно настроить с помощью IEqualityComparer
(как в случае например, в словаре.) В этом случае приведенный выше код не будет возвращать фактическую запись в словаре, а запись с ключом, который вы указали для поиска. К сожалению, нет эффективного способа поиска исходного ключа - вам придется перебирать словарь: (
1 Я знал, что вы можете перебирать словарный запас и находить соответствующую запись таким образом, но я не вижу причин, почему вы когда-нибудь захотите это сделать, когда у вас есть отличный индекс, который является O (1) вместо O (N).
Ответ 2
Как Dictionary<TKey, TValue>
реализует IEnumerable<KeyValuePair<TKey, TValue>>
, вы можете использовать linq:
var pair = _dictionary.SingleOrDefault(p => p.Key == myKey);
Ответ 3
Мы не можем добраться до "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"
Кажется, что нет O (1) -решения с текущим API, но работает цикл через все записи:
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));
}
Ответ 4
Для меня myDict.AsEnumerable
делает это...