IEnumerable<T> to IDictionary<U, IEnumerable<T>>

1k Views Asked by At

What's the most efficient way to convert an IEnumerable<T> to an IDictionary<U, IEnumerable<T>>

Where U is, for example a Guid, for which the information is held in a property of T.

Basically, this creates a dictionary of lists where all items in the original list are grouped based on a value in a property within the objects.

EXAMPLE

Object Definition:

class myObject
{
    public Guid UID { get; set; }

    // other properties
}

Start with:

IEnumerable<myObject> listOfObj;

End with:

IDictionary<Guid, IEnumerable<myObject>> dictOfLists;

Whereby listOfObj contains objects that have many different, but sometimes overlapping values for the UID property.

4

There are 4 best solutions below

7
On BEST ANSWER

Using LINQ:

var dict = input.GroupBy(elem => elem.Identifier)
                .ToDictionary(grouping => grouping.Key, grouping => grouping.Select(x => x));
2
On

I think you might want something like:

var dictionary = list.GroupBy(i => i.Guid,
                              (guid, i) => new { Key = guid, i })
                     .ToDictionary(i => i.Key, i => i);

This would group the original list on common Guids and then give you a dictionary with that Guid as the key.

1
On

The most efficient way to convert is definitely writing an implementation of IDictionary<U, IEnumerable<T>> interface, which accepts an IEnumerable<T> in the constructor, and implements all the operations on the fly using lookups into the given IEnumerable<T>. This way the conversion itself is O(1).

However such an implementation would have not a good performance (but this is unrelated to the conversion efficiency).

0
On

An ILookup<U,T> as a "collection of keys mapped to one or more values" is not identical to an IDictionary<U, IEnumerable<T>> but it is equivalent, and in some ways better. It's certainly easy to create:

var myLookup = listOfObj.ToLookup(x => x.UID);