C# - LINQ - 按日期范围分组集合

Posted

技术标签:

【中文标题】C# - LINQ - 按日期范围分组集合【英文标题】:C# - LINQ - Group collection by date range 【发布时间】:2021-06-09 19:40:50 【问题描述】:

假设我有以下项目集合:

ID: 1, Date: 10/01/2020 08:00
ID: 2, Date: 10/01/2020 12:00
ID: 3, Date: 10/01/2020 18:00
ID: 4, Date: 11/01/2020 06:00
ID: 5, Date: 11/01/2020 08:00

ID: 6, Date: 11/01/2020 08:01
ID: 7, Date: 11/01/2020 12:00
ID: 8, Date: 12/01/2020 01:00
ID: 9, Date: 12/01/2020 07:00

ID: 10, Date: 12/01/2020 12:00
ID: 11, Date: 12/01/2020 14:00
ID: 12, Date: 12/01/2020 16:00

基于上述集合,我想创建 3 个组,其中包含按时间间隔分组的记录 - 从一个小时 08:00 到第二天 07:59:

XX.01.2020 08:00 - XX(+1).01.2020 07:59

输出分组集合应如下所示

**Group 1 (10.01.2020 08:00 - 11.01.2020 07:59):**
   ID: 1, Date: 10/01/2020 08:00
   ID: 2, Date: 10/01/2020 12:00
   ID: 3, Date: 10/01/2020 18:00
   ID: 4, Date: 11/01/2020 06:00
   ID: 5, Date: 11/01/2020 07:59
**Group 2 (11.01.2020 08:00 - 12.01.2020 07:59):**
   ID: 6, Date: 11/01/2020 08:00
   ID: 7, Date: 11/01/2020 12:00
   ID: 8, Date: 12/01/2020 01:00
   ID: 9, Date: 12/01/2020 07:00
**Group 3 (12.01.2020 08:00 - 13.01.2020 07:59):**
   ID: 10, Date: 12/01/2020 12:00
   ID: 11, Date: 12/01/2020 14:00
   ID: 12, Date: 12/01/2020 16:00

这可以使用 Linq 吗? 提前谢谢你

【问题讨论】:

到目前为止你尝试过什么?你卡在哪里了? 【参考方案1】:

我不知道你有什么收藏,但假设你有Dictionary<int, DateTime>

然后你可以像这样分组,如果在 8 点之后“四舍五入”到当天,如果在 8 点之前,则“四舍五入”到前一天:

    var groups = dictionary.GroupBy(x =>
        
            var dt = x.Value;
            if (dt.Hour >= 8)
                return dt.Date;
            else
                return dt.Subtract(TimeSpan.FromHours(24)).Date;
        );

【讨论】:

【参考方案2】:

您没有指定是否要在数据库中运行。

但我认为一个非常简单的方法是减去 8 小时,使其成为一整天,您可以将其用作分组的基础:

var result = list.GroupBy(x => x.Date.AddHours(-8).Date);

如果你想得到一个正确的“从”和“到”日期分组,就像你似乎指定的那样,你可以把这个投影拍到最后:

    .Select(g => new 
        From = g.Key.AddHours(8),
        To = g.Key.AddHours(8).AddDays(1),
        Values = g.AsEnumerable()
    );

这可能适用于内存集合上的普通 Linq。如果你在IQueryable 上运行它,它不会被翻译成 SQL(除非我很迟钝)。

如果您认为其他答案更好,则可以接受。 :)

【讨论】:

以上是关于C# - LINQ - 按日期范围分组集合的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL 中查找按日期分组的集合中的平均最低项

按日期范围分组 mongodb

使用 C# 、 LINQ 进行排序

按日期对来自多个集合的文档进行分组

LINQ 按时间段聚合和分组

C# LINQ - 按属性分组列表,然后按不同组选择