c# – 如何使用Linq获取不在一段时间内的前两个连续日期时间点?
我有一个日期时间值列表.我想获得前两个连续的日期时间值
使用 Linq驻留在时间范围之外.我不知道该怎么做. 示例数据(可以复制到LinqPad: List<DateTime> list = new List<DateTime> { DateTime.Parse("07/08/2014 01:00 AM"),DateTime.Parse("07/08/2014 02:00 AM"),DateTime.Parse("07/08/2014 03:00 AM"),DateTime.Parse("07/08/2014 04:00 AM"),DateTime.Parse("07/08/2014 05:00 AM"),}; DateTime blackoutStartTime = DateTime.Parse("07/08/2014 02:00 AM"); DateTime blackoutEndTime = DateTime.Parse("07/08/2014 03:00 AM"); 我试过这个是错的: var twoHours = list.Where(e => e <= blackoutStartTime || e >= blackoutEndTime) .Take(2); 我期待结果是最后两个小时,凌晨4点和凌晨5点.在任何示例中,两个小时应该在停电时间范围之前(如果有至少两个小时)或在停电时间范围之后(如此处的示例). 解决方法
它不是非常高效也不是非常易读,但您可以在单个查询中执行此操作(请参阅底部的有效解决方案):
var twoHours = list.Where(d => d < blackoutStartTime || blackoutEndTime < d) .OrderBy(d => d) // if sequence is not ordered .GroupBy(d => blackoutEndTime < d) .OrderBy(g => g.Key) .Select(g => g.Take(2)) .Where(g => g.Count() == 2) .SelectMany(g => g) .Take(2); 输出: 7/8/2014 04:00:00 7/8/2014 05:00:00 说明: >筛选出不在范围内的日期 – 我们不需要它们 更有效的方法(如果序列被排序,否则你应该在查询之前对它进行排序) – Jim Mischel的一点改进建议(为了更好的可读性,我会采用两种查询方式): var twoHours = list.TakeWhile(d => d < blackoutStartTime).Take(2).ToList(); if (twoHours.Count < 2) twoHours = list.SkipWhile(d => d <= blackoutEndTime).Take(2).ToList(); 改进了什么 – 您不需要将每个查询结果保存到列表中.这将枚举所有匹配条件的项目并在内存中创建新列表.如果你在范围之前有很多项目,或者你在范围之前有少于两个项目而在范围之后有很多项目 – 这不是你想要的.因此,只需要前两项并将它们保存到列表中.在理想世界中,您只会枚举前两个项目.如果没有,那么你将枚举所有项目,直到范围结束2. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |