使用Linq,如何对目标对象中的列表中的对象进行GroupBy

Tom*_*Tom 6 c# linq grouping

可能措辞不对,但这就是我所拥有的,这是我想要实现的结果:

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"}});
Run Code Online (Sandbox Code Playgroud)

我想用ingrediant分组蛋糕.所以我想最终得到这个:

 - Sugar
        Cake1
        Cake2
 - Stevia
        Cake3 
 - Chocolate
        Cake1
 - Butter
        Cake2
        Cake3
Run Code Online (Sandbox Code Playgroud)

提前致谢!

dev*_*zer 8

如果你不介意查询理解,这里有一个替代方案(注意更正的拼写):

IEnumerable<IGrouping<string,Cake>> query =
    from cake in cakes
    from ingredient in cake.Ingredients
    group cake by ingredient;
Run Code Online (Sandbox Code Playgroud)

惊喜!这是一个有效的查询!语言规范允许理解以分组结尾.从IGrouping<string,Cake>技术上讲,IEnumerable<Cake>它具有Key类型的属性string- 在这种情况下是成分.编译器将其转换为几乎与其他答案完全相同的代码.

我们可以通过引入一个intoselect查询继续有效的子句来改变查询以生成与其他答案类似的相同泛型类型:

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() };
Run Code Online (Sandbox Code Playgroud)

恕我直言,fluent语法和查询语法都值得了解.干杯!

  • +1 Nice,查询语法在这种情况下更具可读性. (2认同)

Lee*_*Lee 6

var ingrediants = cakes.SelectMany(c => c.Ingrediants.Select(i => new { Cake = c, Ingrediant = i }))
    .GroupBy(ci => ci.Ingrediant)
Run Code Online (Sandbox Code Playgroud)

然后组密钥是成分名称,组集合是匹配的蛋糕.