LINQ表达式:指定最大groupby大小

时间:2015-10-06 12:19:12

标签: c# linq

在LINQ中是否有一种优雅的关注方式,或者我应该为此

编写扩展名

我有一个需要按startdate分组的对象列表

让我们说

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 个答案:

答案 0 :(得分: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)));

这是对正在发生的事情的分解。注意大括号表示集合,square表示具有多个属性的对象。

初始数据

  

09.00,13.00,13.00,13.00,15.00

GroupBy(x => x.StartDate)之后

  

[Key:09.00,{09.00}],[Key: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)

之后
  

{[Key: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 :(得分:0)

如果我正确理解您的问题,您可以使用from itertools import compress main_list = [12, 10, 30, 10, 11,10, 31] get_indices = [1, 0, 1, 1, 0, 0, 0] print list(compress(main_list, get_indices)) [12, 30, 10]

Take

每个小组最多包含2个成员,其他小组不会返回。