Tricky Linq Group的时间范围

时间:2009-04-16 02:41:34

标签: c# linq datetime linq-group

我有一个班级代表员工可以工作的班次:

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;

我的问题:对于每一天,如何在不重复计算的情况下,在不同的组中获得重叠的所有轮班?

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

如果可能的话,我希望能够用linq做到这一点。

2 个答案:

答案 0 :(得分:3)

首先,我认为如果您为每个班次提供一些唯一标识符会更容易,以便您可以区分它。然后我认为你可以使用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 );
    }
}

答案 1 :(得分:2)