Подтвердить что ты не робот

Получение 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])?

4b9b3361

Ответ 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 делает это...