Reputation:
I have the following object in a list:
public class DemoClass
{
public int GroupKey { get; set; }
public string DemoString { get; set; }
public object SomeOtherProperty { get; set; }
}
Now, I want to create following dictionary out of it:
Dictionary<int, List<DemoClass>>
I want to group the List<DemoClass>
by the property GroupKey
, but I don't understand how this is done and some help.
After thinking a bit, I achieved the needed behaviour with:
var groupedDemoClasses = from demoClass in mySepcialVariableWhichIsAListOfDemoClass
group demoClass by demoClass.GroupKey
into groupedDemoClass
select groupedDemoClass;
var neededDictionary = groupedDemoClass.ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());
but, is there a way to make this into a single statement?
Upvotes: 121
Views: 84162
Reputation: 13092
var groupedDemoClasses = (from demoClass in mySepcialVariableWhichIsAListOfDemoClass
group demoClass by demoClass.GroupKey
into groupedDemoClass
select groupedDemoClass).ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());
This one will work !!!
Upvotes: 93
Reputation: 9428
I'm going slightly off topic here, but I got to this thread becausde I was looking for a way to create a dictionary of a dictionary in Linq, and the conversation here lead me to the answer...
You can use linq to create multi-level dictionaries, which is useful for scenarios where you've got more than 1 key or dimension that you want to search by. The trick is to create a grouping and then convert it to a dictionary, as follows:
Dim qry = (From acs In ActualSales _
Group By acs.ProductID Into Group _
Select ProductID, Months = Group.ToDictionary(Function(c) c.Period) _
).ToDictionary(Function(c) c.ProductID)
The resulting query can be used as follows:
If qry.ContainsKey(_ProductID) Then
With qry(_ProductID)
If .Months.ContainsKey(_Period) Then
...
End If
End With
End If
Hope this is helpful to anyone else who needs this sort of query.
Upvotes: 4
Reputation: 1500215
Just to make mquander's suggestion concrete:
var groupedDemoClasses = mySpecialVariableWhichIsAListOfDemoClass
.GroupBy(x => x.GroupKey)
.ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());
You'd make it shorter if you used shorter variable names too, of course :)
However, might I suggest that a Lookup might be more appropriate? A Lookup is basically a dictionary from a key to an IEnumerable<T>
- unless you really need the values as a list, it makes the code even shorter (and more efficient) with the ToLookup call:
var groupedDemoClasses = mySpecialVariableWhichIsAListOfDemoClass
.ToLookup(x => x.GroupKey);
Upvotes: 221
Reputation: 71935
You already made it a one-liner. Just put the ToDictionary
at the end of your first line. If you want it to be shorter, use the functional composition syntax instead of the query syntax.
Upvotes: 7