Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert List<MyObject> to Dictionary <obj.string, List<obj.ID>>

Tags:

c#

.net

linq

I would like to take a list of objects and convert it to a dictionary where the key is a field in the object, and the value is a list of a different field in the objects that match on the key. I can do this now with a loop but I feel this should be able to be accomplished with linq and not having to write the loop. I was thinking a combination of GroupBy and ToDictionary but have been unsuccessful so far.

Here's how I'm doing it right now:

var samplesWithSpecificResult = new Dictionary<string, List<int>>(); foreach(var sample in sampleList) {     List<int> sampleIDs = null;     if (samplesWithSpecificResult.TryGetValue(sample.ResultString, out sampleIDs))     {         sampleIDs.Add(sample.ID);         continue;     }     sampleIDs = new List<int>();     sampleIDs.Add(sample.ID);     samplesWithSpecificResult.Add(sample.ResultString, sampleIDs); } 

The farthest I can get with .GroupBy().ToDictionay() is Dictionary<sample.ResultString, List<sample>>.

Any help would be appreciated.

like image 261
Marcus Avatar asked Sep 30 '11 18:09

Marcus


People also ask

How do you turn an object into a dictionary?

I found it easy to json serialize the object and deserialize as a dictionary. var json = JsonConvert. SerializeObject(obj); var dictionary = JsonConvert. DeserializeObject<Dictionary<string, string>>(json);

Can we convert list to object?

In short, to convert an ArrayList to Object array you should: Create a new ArrayList. Populate the arrayList with elements, using add(E e ) API method of ArrayList. Use toArray() API method of ArrayList.


2 Answers

Try the following

var dictionary = sampleList     .GroupBy(x => x.ResultString, x => x.ID)     .ToDictionary(x => x.Key, x => x.ToList()); 

The GroupBy clause will group every Sample instance in the list by its ResultString member, but it will keep only the Id part of each sample. This means every element will be an IGrouping<string, int>.

The ToDictionary portion uses the Key of the IGrouping<string, int> as the dictionary Key. IGrouping<string, int> implements IEnumerable<int> and hence we can convert that collection of samples' Id to a List<int> with a call to ToList, which becomes the Value of the dictionary for that given Key.

like image 157
JaredPar Avatar answered Sep 20 '22 21:09

JaredPar


Yeah, super simple. The key is that when you do a GroupBy on IEnumerable<T>, each "group" is an object that implements IEnumerable<T> as well (that's why I can say g.Select below, and I'm projecting the elements of the original sequence with a common key):

var dictionary =      sampleList.GroupBy(x => x.ResultString)                .ToDictionary(                    g => g.Key,                    g => g.Select(x => x.ID).ToList()      ); 

See, the result of sampleList.GroupBy(x => x.ResultString) is an IEnumerable<IGrouping<string, Sample>> and IGrouping<T, U> implements IEnumerable<U> so that every group is a sequence of Sample with the common key!

like image 26
jason Avatar answered Sep 19 '22 21:09

jason