如何用LINQ按分钟/5分钟间隔过滤集合,取最接近间隔起始的首项?
按时间增量过滤集合的LINQ实现方案
嘿,我来帮你搞定这两个时间过滤的问题!核心思路都是先按指定的时间间隔分组,再在每个分组里筛选出符合要求的首个数据,下面分情况详细说明:
问题1:按更小的时间增量过滤集合的通用思路
要实现按任意时间增量(比如1分钟、5分钟、1小时等)过滤,关键步骤是:
- 为每个数据项计算它所属的时间间隔起始时刻(比如12:01:10属于12:01:00这个1分钟间隔,12:02:45属于12:02:00)
- 用这个起始时刻作为分组键,把数据按间隔分组
- 在每个分组内按时间排序,取最接近起始时刻的首个数据(通常是组内时间最早的项)
问题2:具体场景的LINQ实现
首先我们先定义对应的数据类(方便代码演示,你也可以直接用匿名类型):
public class PriceData { public decimal Price { get; set; } public DateTime DateTime { get; set; } }
场景1:保留每个分钟起始时刻最接近的首个数据
针对你给出的示例集合,我们可以这样写LINQ查询:
var originalData = new List<PriceData> { new PriceData { Price = 123.45m, DateTime = DateTime.Parse("01/01/18 12:01:10") }, new PriceData { Price = 89.23m, DateTime = DateTime.Parse("01/01/18 12:01:20") }, new PriceData { Price = 66.13m, DateTime = DateTime.Parse("01/01/18 12:01:30") }, new PriceData { Price = 75.00m, DateTime = DateTime.Parse("01/01/18 12:02:45") } }; var filteredPerMinute = originalData // 按"分钟起始时刻"分组:把时间截断到当前分钟的0秒 .GroupBy(item => new DateTime( item.DateTime.Year, item.DateTime.Month, item.DateTime.Day, item.DateTime.Hour, item.DateTime.Minute, 0)) // 每个分组内按时间升序排列,取第一个(最接近分钟起始的项) .Select(group => group.OrderBy(item => item.DateTime).First()) .ToList();
运行后filteredPerMinute就会得到你想要的结果:
[ {Price:123.45, DateTime:01/01/18 12:01:10}, {Price:75.00, DateTime:01/01/18 12:02:45} ]
场景2:保留每5分钟间隔起始时刻最接近的首个数据
只需要修改分组键的计算逻辑,把时间截断到最近的5分钟起始点(比如12:01:10属于12:00:00,12:02:45属于12:00:00,12:05:30属于12:05:00):
var filteredPer5Minutes = originalData // 按"5分钟起始时刻"分组:计算当前分钟所属的5分钟区间起始 .GroupBy(item => { var dt = item.DateTime; // 把分钟数向下取整到最近的5的倍数 int roundedMinute = (dt.Minute / 5) * 5; return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, roundedMinute, 0); }) // 同样取分组内时间最早的项 .Select(group => group.OrderBy(item => item.DateTime).First()) .ToList();
如果你的原始数据里有12:05:10的项,它会被分到12:05:00的组里,和同组的其他项比较后取最早的那个。
额外说明
- 如果你的需求是取每个间隔内最接近起始时刻的项(不管早晚),可以计算每个项和间隔起始的时间差绝对值,然后取差值最小的那个,代码可以改成:
.Select(group => group.OrderBy(item => Math.Abs((item.DateTime - group.Key).Ticks)).First()) - 注意处理DateTime的时区问题,如果你的时间是UTC或者带时区的,要统一转换后再计算分组键。
内容的提问来源于stack exchange,提问作者user8570495
相关产品推荐
相关产品推荐

