34

Is there streamlined way to convert list/enumberable of KeyValuePair<T, U> to Dictionary<T, U>?

Linq transformation, .ToDictionary() extension did not work.

nvoigt
  • 75,013
  • 26
  • 93
  • 142
Nenad
  • 24,809
  • 11
  • 75
  • 93
  • 1
    When you say *it didn't work,* **what** didn't work? Couldn't compile? Didn't return the output you expected? Exception? – Anthony Pegram Oct 21 '11 at 13:50
  • Check [this](http://stackoverflow.com/questions/2636603/recreating-a-dictionary-from-an-ienumerable) post Similar Question – Emmanuel N Oct 21 '11 at 13:51
  • Does this answer your question? [Recreating a Dictionary from an IEnumerable>](https://stackoverflow.com/questions/2636603/recreating-a-dictionary-from-an-ienumerablekeyvaluepair) – nvoigt Jan 04 '22 at 09:30
  • @nvoigt It's basically the same topic. Maybe less noisy and more to the point on this thread. – Nenad Jan 05 '22 at 14:56

4 Answers4

68
.ToDictionary(kvp=>kvp.Key,kvp=>kvp.Value);

Isn't that much more work.

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
13

You can create your own extension method that would perform as you expect.

public static class KeyValuePairEnumerableExtensions
{
    public static Dictionary<TKey, TValue> ToDictionary<TKey, TValue>(this IEnumerable<KeyValuePair<TKey, TValue>> source)
    {
        return source.ToDictionary(item => item.Key, item => item.Value);
    }
}
JG in SD
  • 5,427
  • 3
  • 34
  • 46
3

This is the best I could produce:

public static IDictionary<TKey, TValue> ToDictionary<TKey, TValue>(IEnumerable<KeyValuePair<TKey, TValue>> keyValuePairs)
{
    var dict = new Dictionary<TKey, TValue>();
    var dictAsIDictionary = (IDictionary<TKey, TValue>) dict;
    foreach (var property in keyValuePairs)
    {
        (dictAsIDictionary).Add(property);
    }
    return dict;
}

I compared the speed of converting an IEnumerable of 20 million key value pairs to a Dictionary using Linq.ToDictionary with the speed of this one. This one ran in 80% of the time of the Linq version. So it's faster, but not a lot. I think you'd really need to value that 20% saving to make it worth using.

Geoff
  • 31
  • 1
2

Similar to the others, but using new instead of ToDictionary (since new already supports KeyValuePair enumerations) and allowing the passing of an IEqualityComparer<TKey>.

Also including a ToReadOnlyDictionary variant for completeness.

public static class EnumerableKeyValuePairExtensions {

    public static Dictionary<TKey, TValue> ToDictionary<TKey, TValue>(this IEnumerable<KeyValuePair<TKey, TValue>> keyValuePairs, IEqualityComparer<TKey>? comparer = null)
    where TKey : notnull
        => new Dictionary<TKey, TValue>(keyValuePairs, comparer);

    public static ReadOnlyDictionary<TKey, TValue> ToReadOnlyDictionary<TKey, TValue>(this IEnumerable<KeyValuePair<TKey, TValue>> keyValuePairs, IEqualityComparer<TKey>? comparer = null)
    where TKey : notnull
        => new ReadOnlyDictionary<TKey, TValue>(keyValuePairs.ToDictionary(comparer));
}
Mark A. Donohoe
  • 28,442
  • 25
  • 137
  • 286