views:

1659

answers:

4

good morning!

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>>

following behaviour is tried to applied: group the List by the property GroupKey
somehow i don't get this done and some help would be appreciated!

regards!

edit:
after thinking a bit, i achieved the neede 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: isn't there any way to make this a "one-liner"?!

+2  A: 

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.

mquander
+4  A: 
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 !!!

Prashant
+10  A: 

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);
Jon Skeet
i thought that a lookup performs not that good, compared to a built dictionary, in a longterm-environment, due it builds up the result fresh for every request... please correct me, if i'm wrong!
Andreas Niedermair
No, it creates the whole lookup. In general, ToXXX doesn't use deferred execution.
Jon Skeet
(You may be thinking of a Grouping, which is indeed deferred.)
Jon Skeet
oh - ok :) thank you!
Andreas Niedermair
If I wasn't so spiteful I'd vote you up. Came for the Linq, stayed for the data structure I've never heard of!
Chris McCall
A: 

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.

Mark