如何用LINQ/Lambda获取日期列表中每年首个存在的条目?
用LINQ轻松提取每年最早的条目
这问题太常见了,你原来的写法硬卡了1月2日,肯定会漏数据。用LINQ的分组+筛选就能完美解决,完全不用嵌套循环,代码还简洁~
核心思路就是:先按年份把所有条目分组,然后在每个年份组里找出日期最早的那个条目就行。
基础实现(清晰易懂)
var yearlyIndex = pModel.IndexData // 先把每个条目和转换后的日期绑定,避免重复调用ConvertToDateTime .Select(index => new { Index = index, Date = index.Date.ConvertToDateTime() }) // 按年份分组,把同一年的条目归到一组 .GroupBy(item => item.Date.Year) // 每个组内按日期排序,取第一个(也就是最早的条目),再提取原始的index对象 .Select(group => group.OrderBy(item => item.Date).First().Index) .ToList();
这段代码针对你的示例:
- 2000年的组里有
2000-01-01和2000-02-03,排序后取第一个就是2000-01-01对应的条目 - 2001年的组里最早的是
2001-03-11,自然会被选中
性能优化版(大数据量推荐)
如果你的数据量很大,OrderBy排序会有点性能开销,用Aggregate直接遍历找最小日期的条目更高效(时间复杂度O(n),排序是O(n log n)):
var yearlyIndex = pModel.IndexData .Select(index => new { Index = index, Date = index.Date.ConvertToDateTime() }) .GroupBy(item => item.Date.Year) // 遍历组内元素,始终保留当前日期最小的条目 .Select(group => group.Aggregate((currentMin, nextItem) => nextItem.Date < currentMin.Date ? nextItem : currentMin ).Index) .ToList();
为什么比你原来的写法好?
你原来的代码只筛选1月2日的条目,完全没考虑每年最早的日期可能不是固定的1月1日或1月2日,而上面的写法不管每年第一个条目是哪一天,都能准确抓出来,通用性强多了。
内容的提问来源于stack exchange,提问作者PEPEGA
相关产品推荐
相关产品推荐

