patterncsharpModerate
Verify if meeting datetime ranges overlap in an IEnumerable list of meetings
Viewed 0 times
verifyrangesmeetingsoverlapmeetinglistdatetimeienumerable
Problem
I have an assignment where I need to find out if any of the meetings in a list of meeting class object have overlapping datetime ranges. What I have so far is this:
Using the provided data set, I get the correct result but as I add more meetings, my results start to fail and performance drops.
I feel that the problem is in how I am iterating the list. However, if I sort the list first, I can most likely improve reliability but my performance would probably drop. I feel that there should be an algorithm for this, but so far, I have not had any luck finding one.
public class Meeting
{
public DateTime Start { get; private set; }
public DateTime End { get; private set; }
public Meeting(DateTime start, DateTime end)
{
this.Start = start;
this.End = end;
}
}
public static class StaffMeetings
{
public static bool DoesNotOverlap(IEnumerable meetings)
{
DateTime start = new DateTime();
DateTime end = new DateTime();
foreach (Meeting meeting in meetings)
{
if (start != DateTime.MinValue && end != DateTime.MinValue)
{
if (start meeting.Start)
{
return false;
}
}
start = meeting.Start;
end = meeting.End;
}
return true;
}
public static void Main(string[] args)
{
var format = System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat;
Meeting[] meetings = new Meeting[]
{
new Meeting(DateTime.Parse("1/1/2015 20:00", format), DateTime.Parse("1/1/2015 21:30", format)),
new Meeting(DateTime.Parse("1/1/2015 21:30", format), DateTime.Parse("1/1/2015 23:00", format)),
new Meeting(DateTime.Parse("1/1/2015 23:10", format), DateTime.Parse("1/1/2015 23:30", format))
};
Console.WriteLine(StaffMeetings.DoesNotOverlap(meetings));
}
}Using the provided data set, I get the correct result but as I add more meetings, my results start to fail and performance drops.
I feel that the problem is in how I am iterating the list. However, if I sort the list first, I can most likely improve reliability but my performance would probably drop. I feel that there should be an algorithm for this, but so far, I have not had any luck finding one.
Solution
Sorting is what actually makes it work but if you also want it to be more linq-ish and more solid then you should change the following things:
Example:
Gets overlapping meetings:
or checks if there are any. It stops at the first overlapping pair found:
with these new extensions you are more flexible because you can easily check any two meetings overlap and it's easier to undestand than
But even this could be further improved by overloading the two `
- move the overlap-logic into another method
- change the method to return an
IEnumerablefor meetings that overlap
- use
Anyto find out whether any meeting overlap
- make both methods extensions
Example:
public static IEnumerable Overlappings(this IEnumerable meetings)
{
var last = (Meeting)null;
foreach (var meeting in meetings.OrderBy(m => m.Start))
{
if (last != null && meeting.OverlapsWith(last))
{
yield return new [] { last, meeting };
}
last = meeting;
}
}
public static bool OverlapsWith(this Meeting x, Meeting y)
{
return x.Start y.Start : y.End > x.Start;
}Gets overlapping meetings:
var overlappingMeetings = meetings.Overlappings();or checks if there are any. It stops at the first overlapping pair found:
var meetingsOverlap = meetings.Overlappings().Any();with these new extensions you are more flexible because you can easily check any two meetings overlap and it's easier to undestand than
DoesNotOverlap. Usually it's better to write positive conditions and negate them if necessary rather than the other way around.But even this could be further improved by overloading the two `
operators:
public static bool operator (Meeting x, Meeting y)
{
return x.End > y.Start;
}
and making the OverlapsWith` method still more natural:public static bool OverlapsWith(this Meeting x, Meeting y)
{
return x.Start x;
}Code Snippets
public static IEnumerable<Meeting[]> Overlappings(this IEnumerable<Meeting> meetings)
{
var last = (Meeting)null;
foreach (var meeting in meetings.OrderBy(m => m.Start))
{
if (last != null && meeting.OverlapsWith(last))
{
yield return new [] { last, meeting };
}
last = meeting;
}
}
public static bool OverlapsWith(this Meeting x, Meeting y)
{
return x.Start < y.Start ? x.End > y.Start : y.End > x.Start;
}var overlappingMeetings = meetings.Overlappings();var meetingsOverlap = meetings.Overlappings().Any();public static bool operator <(Meeting x, Meeting y)
{
return x.End < y.Start;
}
public static bool operator >(Meeting x, Meeting y)
{
return x.End > y.Start;
}public static bool OverlapsWith(this Meeting x, Meeting y)
{
return x.Start < y.Start ? x < y : y > x;
}Context
StackExchange Code Review Q#144567, answer score: 10
Revisions (0)
No revisions yet.