LINQ表达式:指定最大分组大小
本文关键字:表达式 LINQ | 更新日期: 2023-09-27 18:16:18
在LINQ中是否有一种优雅的方式来执行以下操作,或者我应该为此编写一个扩展
我有一个对象列表,需要按开始日期分组
让说
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}
在初始分组之后,您可以按索引(在组中)除以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}],[关键:15.00,{15.00}]
现在它将对每一组进行操作,但我将显示每一步对所有组的结果。Select((x,i) => new{x,i})
{[x: 09.00,我:0]},{[x: 13.00,我:0],[x: 13.00,我:1],[x: 13.00,我:2]},{[x: 15.00,我:0]}
GroupBy(a => a.i / 2)
后
{(关键:0,{[x: 09.00,我:0]}]},{(关键:0,{[x: 13.00,我:0],[x: 13.00,我:1]}],[关键:1、{[x: 13.00,我:2]}},{(关键:0,{[x: 15.00,我: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));
更新:在。net 6中,他们添加了新的Linq方法Chuck
,它与上面的Bin
方法做同样的事情。现在你可以输入
var result = startDate
.GroupBy(x => x.StartDate)
.SelectMany(grp => grp.Chunk(2));
如果我正确理解你的问题,你可以使用Take
:
var result= startDate.GroupBy(x => x.StartDate)
.Select(x => x.Take(2))
.ToList();
每个组最多包含2个成员,组中的其他项将不返回。