Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert IEnumerable of KeyValuePair<x, y> to Dictionary?

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

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

like image 673
Nenad Avatar asked Oct 21 '11 13:10

Nenad


4 Answers

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

Isn't that much more work.

like image 138
Damien_The_Unbeliever Avatar answered Sep 24 '22 19:09

Damien_The_Unbeliever


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);
    }
}
like image 40
JG in SD Avatar answered Sep 25 '22 19:09

JG in SD


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.

like image 24
Geoff Avatar answered Sep 23 '22 19:09

Geoff


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));
}
like image 33
Mark A. Donohoe Avatar answered Sep 25 '22 19:09

Mark A. Donohoe