c# - LINQ 表达式 : Specifing maximum groupby size

标签 c# linq

在 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)));

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

初始数据

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));

更新:从 .Net 6 开始,他们添加了新的 Linq 方法 Chuck,它与我上面的 Bin 方法做同样的事情。所以现在你可以做

var result = startDate
    .GroupBy(x => x.StartDate)
    .SelectMany(grp => grp.Chunk(2));

关于c# - LINQ 表达式 : Specifing maximum groupby size,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32969801/

相关文章:

c# - 将 Xml 代码段作为参数传递到 xslt

c# - 在 Linq C# 中按单列分组

c# - 使用 Linq 有条件地更改数据表列的值

c# - Asp.Net 连接表,以便它们可以正确排序 C# LINQ

C# 查看特定 .NET 类的源代码

c# - 计算查询耗时

c# - 多个枚举描述

c# - c# 中的事件处理程序和应用程序生命周期对象——我应该取消 Hook 吗?

c# - 合并列表中的重复项

c# - CodePlex 对表达式树序列化库的看法?