Getting a KeyValuePair<> directly from a Dictionary<>

后端 未结 4 1369
忘了有多久
忘了有多久 2021-01-03 18:15

I have System.Collections.Generic.Dictionary dict where A and B are classes, and an instance A a (where dict.ContainsKey(a)

相关标签:
4条回答
  • 2021-01-03 18:37

    We can't get to "IPHone" this way:

    var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
                   {
                       { "IPHone", "TCP/IP honing tools" }
                   };
    
    Console.WriteLine(dict["iPhone"]); // "TCP/IP honing tools"
    Console.WriteLine( ??? ); // "IPHone"
    

    There's seems to be no O(1) solution with the current API, but looping through all entries works:

    var keyValue = dict.First(p => dict.Comparer.Equals(p.Key, "iPhone"));
    
    Console.WriteLine(keyValue.Key); // "IPHone"
    Console.WriteLine(keyValue.Value); // "TCP/IP honing tools"
    

    Or as an extension for the lazy:

    [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));
    }
    
    0 讨论(0)
  • 2021-01-03 18:41

    As Dictionary<TKey, TValue> implements IEnumerable<KeyValuePair<TKey, TValue>>, you could use linq:

    var pair = _dictionary.SingleOrDefault(p => p.Key == myKey);
    
    0 讨论(0)
  • 2021-01-03 18:45

    You need to create a new KeyValuePair1 - but bear in mind that KVP is a value type (a struct) anyway, so it's not like you're introducing a new inefficiency by doing this. Any method returning a KVP would be creating a copy anyway - you're just creating the instance directly.

    You could always add an extension method to IDictionary<TKey, TValue> if you wanted:

    public static KeyValuePair<TKey, TValue> GetEntry<TKey, TValue>
        (this IDictionary<TKey, TValue> dictionary,
         TKey key)
    {
        return new KeyValuePair<TKey, TValue>(key, dictionary[key]);
    }
    

    As noted in comments, it's entirely possible that the key which is stored in the dictionary is not the same as the one provided, just semantically equal - by some semantics which could be customized by an IEqualityComparer (as with a case-insensitive dictionary, for example.) In that case, the code above would not return the actual entry in the dictionary, but an entry with the key you provided to look up. Unfortunately there's no efficient way of finding the original key - you'd have to iterate over the dictionary :(


    1 I was aware that you could iterate over the dictionary entries and find the appropriate entry that way, but I can see no reason why you'd ever want to do so when you've got a perfectly good indexer which is O(1) instead of O(N).

    0 讨论(0)
  • 2021-01-03 18:46

    For me myDict.AsEnumerable does it...

    0 讨论(0)
提交回复
热议问题