Tricky Linq Group по временным диапазонам - PullRequest
1 голос
/ 16 апреля 2009

У меня есть класс, представляющий смену, на которую может работать сотрудник:

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 ]

3 голосов
/ 16 апреля 2009

Во-первых, я думаю, было бы проще, если бы вы дали каждому сдвигу какой-то уникальный идентификатор, чтобы вы могли его различить. Тогда я думаю, что вы можете использовать Где, чтобы выбрать каждый элемент, который имеет какие-либо конфликты с другим элементом в коллекции. Наконец вы можете сгруппировать их по дням. Обратите внимание, что это не скажет вам, какие конфликты сдвигов, только те, которые имеют конфликт в любой данный день.

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 );
    }
}
2 голосов
/ 16 апреля 2009
...