如何在linq中对组进行子组?

时间:2010-06-23 00:00:53

标签: linq linq-to-objects

我正在尝试使用linq对组进行子组。事实证明这比我想象的要困难得多。到目前为止,我采取了快速而肮脏的方法,但它没有我想要的那么高效。这两个linq语句可以简化为一个吗?:

        var basketBalls = from Ball ball in Balls
                        where ball.IsBasketBall())
                        group ball by new { Color = ball.Color, IsBasketBall= ball.IsBasketBall(), Size = ball.Size } into Group
                        where Group.Count() > 0
                        select Group;

        var nonBasketBalls = from Ball ball in Balls
                        where !ball.IsBasketBall())
                        group ball by new { Color = ball.Color, IsBasketBall= ball.IsBasketBall(), Size = ball.Size, Material = ball.Material } into Group
                        where Group.Count() > 0
                        select Group;

以下是两种陈述试图用简单的英语做的事情。找到所有篮球,并按颜色和大小分组。如果他们不是篮球,那么按颜色,大小和材料分组。是否可以用简洁的linq语句来做到这一点?

1 个答案:

答案 0 :(得分:2)

使这一点变得困难的关键问题是,您获得的两个结果的类型不同,因为这两个查询使用不同的键 - 这意味着结果类型不同。

但是,根据IsBasketBall是否为真,您可以将球分为两组。然后,您可以执行嵌套分组,但键的类型必须相同。您可以使用“较大”类型(包括Material)来实现此目的,但您可以对购物篮中的元素使用一些DefaultMaterial值 - 这意味着该材料实际上不会用于分组:

var basketBalls = 
   from Ball ball in Balls 
   group ball by ball.IsBasketBall() into g
   select new {
     IsBasketBall = g.Key,
     Elements = from b in g 
                group b by new { 
                  Color = ball.Color, IsBasketBall= g.Key, Size = ball.Size, 
                  Material = g.Key ? DefaultMaterial : ball.Material }
   }