使用LINQ按日期对序列进行分组,没有间隔

编程入门 行业动态 更新时间:2024-10-25 11:21:33
本文介绍了使用LINQ按日期对序列进行分组,没有间隔的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在尝试选择一个列表的子组,其中项目具有连续的日期,例如

I'm trying to select a subgroup of a list where items have contiguous dates, e.g.

ID StaffID Title ActivityDate -- ------- ----------------- ------------ 1 41 Meeting with John 03/06/2010 2 41 Meeting with John 08/06/2010 3 41 Meeting Continues 09/06/2010 4 41 Meeting Continues 10/06/2010 5 41 Meeting with Kay 14/06/2010 6 41 Meeting Continues 15/06/2010

我每次都使用一个枢轴点,因此将示例枢轴项设为3,我希望围绕枢轴获得以下结果连续事件:

I'm using a pivot point each time, so take the example pivot item as 3, I'd like to get the following resulting contiguous events around the pivot:

ID StaffID Title ActivityDate -- ------- ----------------- ------------ 2 41 Meeting with John 08/06/2010 3 41 Meeting Continues 09/06/2010 4 41 Meeting Continues 10/06/2010

我当前的实现方式是费力地走"过去,然后走到未来,以建立列表:

My current implementation is a laborious "walk" into the past, then into the future, to build the list:

var activity = // item number 3: Meeting Continues (09/06/2010) var orderedEvents = activities.OrderBy(a => a.ActivityDate).ToArray(); // Walk into the past until a gap is found var preceedingEvents = orderedEvents.TakeWhile(a => a.ID != activity.ID); DateTime dayBefore; var previousEvent = activity; while (previousEvent != null) { dayBefore = previousEvent.ActivityDate.AddDays(-1).Date; previousEvent = preceedingEvents.TakeWhile(a => a.ID != previousEvent.ID).LastOrDefault(); if (previousEvent != null) { if (previousEvent.ActivityDate.Date == dayBefore) relatedActivities.Insert(0, previousEvent); else previousEvent = null; } } // Walk into the future until a gap is found var followingEvents = orderedEvents.SkipWhile(a => a.ID != activity.ID); DateTime dayAfter; var nextEvent = activity; while (nextEvent != null) { dayAfter = nextEvent.ActivityDate.AddDays(1).Date; nextEvent = followingEvents.SkipWhile(a => a.ID != nextEvent.ID).Skip(1).FirstOrDefault(); if (nextEvent != null) { if (nextEvent.ActivityDate.Date == dayAfter) relatedActivities.Add(nextEvent); else nextEvent = null; } }

列表relatedActivities然后应按顺序包含连续事件.

The list relatedActivities should then contain the contiguous events, in order.

是否有更好的方法(也许使用LINQ)?

我想到了使用 .Aggregate() ,但是当它在序列中发现缺口时,却想不出如何使聚合爆发.

I had an idea of using .Aggregate() but couldn't think how to get the aggregate to break out when it finds a gap in the sequence.

推荐答案

在这种情况下,我认为标准的foreach循环可能比LINQ查询更具可读性:

In this case I think that a standard foreach loop is probably more readable than a LINQ query:

var relatedActivities = new List<TActivity>(); bool found = false; foreach (var item in activities.OrderBy(a => a.ActivityDate)) { int count = relatedActivities.Count; if ((count > 0) && (relatedActivities[count - 1].ActivityDate.Date.AddDays(1) != item.ActivityDate.Date)) { if (found) break; relatedActivities.Clear(); } relatedActivities.Add(item); if (item.ID == activity.ID) found = true; } if (!found) relatedActivities.Clear();

对于它的价值,这是一个大致等效的LINQ查询,而且可读性差得多:

For what it's worth, here's a roughly equivalent -- and far less readable -- LINQ query:

var relatedActivities = activities .OrderBy(x => x.ActivityDate) .Aggregate ( new { List = new List<TActivity>(), Found = false, ShortCircuit = false }, (a, x) => { if (a.ShortCircuit) return a; int count = a.List.Count; if ((count > 0) && (a.List[count - 1].ActivityDate.Date.AddDays(1) != x.ActivityDate.Date)) { if (a.Found) return new { a.List, a.Found, ShortCircuit = true }; a.List.Clear(); } a.List.Add(x); return new { a.List, Found = a.Found || (x.ID == activity.ID), a.ShortCircuit }; }, a => a.Found ? a.List : new List<TActivity>() );

更多推荐

使用LINQ按日期对序列进行分组,没有间隔

本文发布于:2023-10-13 09:44:38,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1487602.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:间隔   序列   按日   LINQ

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!