Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Linq, how to GroupBy against objects in a list within the target object

Tags:

c#

linq

grouping

Might not be worded quite right but here's what I have and here's the result I want to achieve:

class Cake
{
public List<string> Ingrediants {get;set;}
public DateTime Baked {get;set;}
public string CakeName {get;set;}
}

List<Cake> cakes= new List<Cake>();
cakes.Add(new Cake() {CakeName = "Cake1", Ingrediants = new List<string>() {"Sugar", "Chocolate"}});
cakes.Add(new Cake() {CakeName = "Cake2", Ingrediants = new List<string>() {"Sugar", "Butter"}});
cakes.Add(new Cake() {CakeName = "Cake3", Ingrediants = new List<string>() {"Stevia", "Butter"}});

I would like to group the cakes by ingrediant. So I'd like to end up with this:

 - Sugar
        Cake1
        Cake2
 - Stevia
        Cake3 
 - Chocolate
        Cake1
 - Butter
        Cake2
        Cake3

Thanks in advance!

like image 778
Tom Avatar asked Jan 28 '13 22:01

Tom


1 Answers

If you don't mind query comprehensions, here's an alternative (note corrected spellings):

IEnumerable<IGrouping<string,Cake>> query =
    from cake in cakes
    from ingredient in cake.Ingredients
    group cake by ingredient;

Surprise! This is a valid query! The language-spec allows comprehensions to end with a group-by. The IGrouping<string,Cake> is technically an IEnumerable<Cake> that has a Key property of type string - in this case the ingredient. The compiler works to turn this into almost identical code to that of the other answers.

We could alter the query to generate the same generic type similar to the other answers by introducing an into and a select clause that works off the query-continuation:

var query =
    from cake in cakes
    from ingredient in cake.Ingredients
    group cake by ingredient into cakesGrouped
    select new { Ingredient = cakesGrouped.Key, 
        Cakes = cakesGrouped.ToList() };

Both fluent-syntax and query-syntax are worth knowing, IMHO. Cheers!

like image 96
devgeezer Avatar answered Nov 05 '22 19:11

devgeezer