2015-10-06 84 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我的回答是基於我對問題的理解。讓我知道什麼預期的結果:) –