棘手的 Linq 时间范围分组依据

发布于 2024-07-16 21:25:30 字数 576 浏览 8 评论 0原文

我有一个类代表员工可以工作的轮班:

public class Shift {
    public int Id { get; set;}
    public DateTime Start {get;set;}
    public DateTime End { get; set;}
    public DayOfWeek Day { get; set;}
}

并说我有一个单个员工的轮班列表:

List<Shift> myShifts;

我知道我可以使用以下 linq 语句按天对轮班进行分组:

var shiftsByDay = from a in myShift
                  group a by a.Day;

我的问题:For每天,如何在不重复计算的情况下获得单独组中所有重叠的班次?

重叠班次是指开始时间或结束时间与另一个班次开始时间或结束时间重叠的班次。

如果可能的话,我希望能够使用 linq 来完成此操作。

I have a class that represents a shift that employee's can work:

public class Shift {
    public int Id { get; set;}
    public DateTime Start {get;set;}
    public DateTime End { get; set;}
    public DayOfWeek Day { get; set;}
}

And say I have a list of these shifts for a single employee:

List<Shift> myShifts;

I know I can get group the shifts by day with the following linq statement:

var shiftsByDay = from a in myShift
                  group a by a.Day;

My question: For each day, how can I get all the shifts that overlap, in separate groups, without double counting?

An overlapping shift is one where either the start or end times overlap with another shifts start or end times.

I'd love to be able to do this with linq if at all possible.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

可是我不能没有你 2024-07-23 21:25:30

首先,我认为如果为每个班次提供一些唯一的标识符以便您可以区分它会更容易。 然后我认为您可以使用Where来选择与集合中的另一个元素有任何冲突的每个元素。 最后您可以按天对它们进行分组。 请注意,这不会告诉您哪个班次发生冲突,只会告诉您在任何一天发生冲突的班次。

public class Shift {
    public int ID { get; set; }
    public DateTime Start {get;set;}
    public DateTime End { get; set;}
    public DayOfWeek Day { get; set;}
}

var query = shifts.Where( s1 => shifts.Any( s2 => s1.ID != s2.ID
                                        && s1.Day == s2.Day
                                        && (s2.Start <= s1.Start && s1.Start <= s2.End)
                                             || (s1.Start <= s2.Start && s2.Start <= s1.End))
                  .GroupBy( s => s.Day );

foreach (var group in query.OrderBy( g => g.Key ))
{
    Console.WriteLine( group.Key ); // Day of Week
    foreach (var shift in group)
    {
         Console.WriteLine( "\t" + shift.ID );
    }
}

First, I think it would be easier if you gave each shift some unique identifier so that you can distinguish it. Then I think you can use Where to choose each element that has any conflicts with another element in the collection. Finally you can group them by day. Note this won't tell you which shifts conflict, just the ones that have a conflict on any given day.

public class Shift {
    public int ID { get; set; }
    public DateTime Start {get;set;}
    public DateTime End { get; set;}
    public DayOfWeek Day { get; set;}
}

var query = shifts.Where( s1 => shifts.Any( s2 => s1.ID != s2.ID
                                        && s1.Day == s2.Day
                                        && (s2.Start <= s1.Start && s1.Start <= s2.End)
                                             || (s1.Start <= s2.Start && s2.Start <= s1.End))
                  .GroupBy( s => s.Day );

foreach (var group in query.OrderBy( g => g.Key ))
{
    Console.WriteLine( group.Key ); // Day of Week
    foreach (var shift in group)
    {
         Console.WriteLine( "\t" + shift.ID );
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文