gpt4 book ai didi

c# - 使用 LINQ 按日期对序列进行无间隙分组

转载 作者:太空狗 更新时间:2023-10-29 22:34:56 26 4
gpt4 key购买 nike

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

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

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 列表应按顺序包含连续的事件。

为此有更好的方法(可能使用 LINQ)吗?

我想到了使用 .Aggregate()但想不出如何让聚合在发现序列中的空缺时爆发。

最佳答案

这是一个实现:

public static IEnumerable<IGrouping<int, T>> GroupByContiguous(
this IEnumerable<T> source,
Func<T, int> keySelector
)
{
int keyGroup = Int32.MinValue;
int currentGroupValue = Int32.MinValue;
return source
.Select(t => new {obj = t, key = keySelector(t))
.OrderBy(x => x.key)
.GroupBy(x => {
if (currentGroupValue + 1 < x.key)
{
keyGroup = x.key;
}
currentGroupValue = x.key;
return keyGroup;
}, x => x.obj);
}

您可以通过减法将日期转换为整数,或者想象一个 DateTime 版本(很容易)。

关于c# - 使用 LINQ 按日期对序列进行无间隙分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3006679/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com