Tricky Linq Group by Time Range

I have a class that represents a shift that an employee can do:

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

And I will say that I have a list of these shifts for one employee:

 List<Shift> myShifts; 

I know that I can move groups with each following linq expression:

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

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

A shiftable shift is one where either the start or end time overlaps with other start or end shift times.

I would like it to be possible with linq, if at all possible.

+1
source share
2 answers
+2
source

Firstly, I think it would be easier if you gave each shift a unique identifier so that you can distinguish it. Then I think you can use Where to select each item that has any conflicts with another item in the collection. Finally, you can group them in the afternoon. Please note that this will not tell you which shifts are in conflict, only those who 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 ); } } 
+3
source

All Articles