2010-06-23 55 views
2

我正在尝试使用linq分组。这证明比我想象的更困难。到目前为止,我采取了一种快速而肮脏的方法,但效果并不像我想的那样高效。这两个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声明中做到这一点?

+0

组总是有至少1个元素,所以在Group.Count()> 0的地方只是浪费。 – 2010-06-23 14:12:25

回答

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 } 
    } 
+0

非常感谢。这个问题应该是有条件的分组。我也可以这样做,它似乎更简洁: var basketBalls =从球中的球球 通过新的球组{Ball.IsBasketBall(),Size = ball.Size, Material = ball.IsBasketBall()? 0:ball.Material} – 2010-06-23 00:57:52

+0

@joe:是的,这应该是可能的 - 这实际上是一个好点。这会使代码更加简洁(你只会将层次结构扁平化,但这很可能)。 – 2010-06-23 01:00:12

相关问题