LINQ:5分钟内按日期范围分组

时间:2018-10-10 16:00:19

标签: c# linq group-by

假设我有以下项目和日期集合:

ItemID: 1, Date: 10/10/2018 11:30 AM
ItemID: 1, Date: 10/10/2018 11:32 AM
ItemID: 1, Date: 10/10/2018 11:33 AM
ItemID: 1, Date: 10/10/2018 11:34 AM
ItemID: 1, Date: 10/10/2018 11:57 AM

ItemID: 2, Date: 10/10/2018 7:45 AM
ItemID: 2, Date: 10/10/2018 7:49 AM

ItemID: 3, Date: 10/10/2018 8:45 AM
ItemID: 3, Date: 10/10/2018 9:13 AM

我想按ItemID和Date分组,但我希望它们的日期按相差5分钟以内的日期分组

在上面的数据集中,将以下分组

ItemID: 1, Date: 10/10/2018 11:30 AM    <-- Grouped with Item 1
ItemID: 1, Date: 10/10/2018 11:32 AM    <-- Grouped with Item 1
ItemID: 1, Date: 10/10/2018 11:33 AM    <-- Grouped with Item 1
ItemID: 1, Date: 10/10/2018 11:34 AM    <-- Grouped with Item 1


ItemID: 1, Date: 10/10/2018 11:57 AM    <-- Not Grouped


ItemID: 2, Date: 10/10/2018 7:45 AM    <-- Grouped with Item 2
ItemID: 2, Date: 10/10/2018 7:49 AM    <-- Grouped with Item 2


ItemID: 3, Date: 10/10/2018 8:45 AM    <-- Not Grouped

ItemID: 3, Date: 10/10/2018 9:13 AM    <-- Not Grouped

分组的对象是彼此相差5分钟以内的对象。

我知道如何在LINQ中按ItemID和日期对它们进行分组,但是我很难按照我的描述对它们进行分组。

到目前为止,我已经尝试过:

var groupedItems = from item in items
              group item by new
              {
                  item.ItemID,
                  item.Date
              } into g
              select g;

2 个答案:

答案 0 :(得分:1)

您可以尝试以下操作:

var groupedItems = items
    .GroupBy(i => i.ItemId, (k, g) => g
        .GroupBy(i => (long)new TimeSpan(i.Date.Ticks - g.Min(e => e.Date).Ticks).TotalMinutes / 5))
    .SelectMany(g => g);

答案 1 :(得分:1)

我为您解决的尝试:

var dates = new List<DateTime>{ ... }; // dates get initialized however your code does it...

var groups = dates.Select(d => 
    d, 
    GroupDate = new DateTime(d.Year, d.Month, d.Day, d.Hour, (d.Minute / 5) * 5, d.Second)})
    .GroupBy(g => g.GroupDate);

分钟的数学运算最终要分成一个5分钟的整数倍。另一个警告是,如果您不关心日/月/年,并且希望按分钟对所有内容进行显式分组,那么请抓取new DateTime(...)并替换为(d.Minute / 5) * 5。不管天/月/年,这将按分钟分组。

希望这会有所帮助!