2015-10-06 63 views
2

是否有这样做下面的LINQ或我应该写这个LINQ表达式:Specifing最大GROUPBY大小

我有需要的开始日期进行分组

让对象列表扩展的优雅的方式说

09.00,13.00 , 13.00,13.00 , 15.00,

var groupedStartDates = startdate.groupby(x => x.StartDate); 

我需要为2

预期结果组的最大尺寸

var groupedStartDates = startDate.GroupBy(x => x.StartDate); 
List 
    list1 {09.00} 
    list2 {13.00; 13.00} 
    list3 {13.00} 
    list4 {15.00} 

回答

8

初始分组后,您可以按索引(在组中)除以2进行进一步分组,然后使用SelectMany将其退出。

var result = startDate.GroupBy(x => x.StartDate) 
         .SelectMany(grp => grp.Select((x,i) => new{x,i}) 
              .GroupBy(a => a.i/2) 
              .Select(sgrp => sgrp.Select(a => a.x))); 

下面是关于正在发生的事情的细节。注意大括号将表示集合,正方形将表示具有多个属性的对象。

初始数据

09.00,13.00,13.00,13.00,15.00

GroupBy(x => x.StartDate) [关键:09.00,{09.00}],[键:13.00, {13.00,13.00,13.00}],[Key:15.00,{15.00}]

现在它将在每个组上进行操作,但是我会在每个步骤中显示所有组的结果。 后Select((x,i) => new{x,i})

{[X:09.00,I:0]},{[X:13.00,I:0],[X:13.00,I:1],[X:13.00,I: 2]},{[X:15.00,I:0]}

GroupBy(a => a.i/2)

{[关键:0,{[X:09.00,I:0]}]}, {[Key:0,{[x:13.00,i:0],[x:13.00,i:1]}],[Key:1,{[x:13.00,i:2]}},{[Key :0,{[x:15.00,i:0]}}

.Select(sgrp => sgrp.Select(a => a.x))

{{09.00}},{{13.00,13.00},{} 13.00},{{15之后。00}}

最后,SelectMany将平坦的。

{09.00},{13.00,13.00},{13.00},{} 15.00

注意,每一行代表一个集合,但我并没有把他们周围的花括号,因为我觉得它使得阅读变得更加困难。

或与扩展方法

public static IEnumerable<IEnumerable<T>> Bin<T>(this IEnumerable<T> items, int binSize) 
{ 
    return items.Select((x,i) => new{x,i}) 
       .GroupBy(a => a.i/binSize) 
       .Select(grp => grp.Select(a => a.x)); 
} 

你可以把它更好一点。

var result = startDate.GroupBy(x => x.StartDate) 
         .SelectMany(grp => grp.Bin(2)); 
+1

upvoted,因为它只是工作!但这正在融化我的思想o.o –

+0

感谢您的一步一步的解释。你是个天才! –

+0

非常感谢您的详细解释和查询。 :) – Rassix

0

如果我正确理解你的问题,你可以使用Take

var result= startDate.GroupBy(x => x.StartDate) 
        .Select(x => x.Take(2)) 
        .ToList(); 

将各组最多包含2个成员,并且其他项目组不会返回。

+1

OP是不是在找我猜。检查预期的输出。 –

+1

这不是问题所在。 –

+0

@RahulSingh我的回答是基于我对问题的理解。让我知道什么预期的结果:) –