I recently got in really deep on a question to find the overlapping meetings and I rewrote a bit of the code and added some things to the code, and I would just like a general review of my code and what I could do to make it even better, maybe performance wise or whatever.
Here is my LINQPad 5 Code Dump, you should be able to copy paste into LINQPad and run it, I don't think I did anything that is too cutting edge.
{
var format = System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat;
Meeting[] meetings = new Meeting[]
{
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)),
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 22:10", format), DateTime.Parse("1/1/2015 22:20", format)),
new Meeting(DateTime.Parse("1/1/2015 23:20", format), DateTime.Parse("1/1/2015 23:50", format)),
new Meeting(DateTime.Parse("1/1/2015 23:20", format), DateTime.Parse("1/2/2015 00:00", format)),
new Meeting(DateTime.Parse("1/2/2015 09:00", format), DateTime.Parse("1/2/2015 12:00", format)),
new Meeting(DateTime.Parse("1/2/2015 09:00", format), DateTime.Parse("1/2/2015 10:00", format)),
new Meeting(DateTime.Parse("1/2/2015 11:00", format), DateTime.Parse("1/2/2015 11:30", format))
};
var overlappingMeetings = meetings.Overlappings();
var meetingsOverlap = meetings.Overlappings().Any();
overlappingMeetings.Dump();
meetingsOverlap.Dump();
}
public static class StaffMeetings
{
public static IEnumerable<Meeting[]> Overlappings(this IEnumerable<Meeting> meetings)
{
var first = (Meeting)null;
var orderedMeetings = meetings.OrderBy(m => m.Start);
var checkedMeetings = new List<Meeting>();
foreach (var meeting in orderedMeetings)
{
if (first != null)
{
checkedMeetings.Add(first);
var uncheckedMeetings = orderedMeetings.Where(x => (x.Start >= first.Start && !(x == first)) && !checkedMeetings.Any(m => m == x));
foreach (var meet in uncheckedMeetings)
{
if (first.OverlapsWith(meet))
{
yield return new[] { first, meet };
}
}
}
first = meeting;
}
}
}
public class Meeting
{
public DateTime Start { get; private set; }
public DateTime End { get; private set; }
public Meeting(DateTime start, DateTime end)
{
if (end < start)
{
throw new ArgumentException("Cannot create a meeting that ends before it starts.");
}
this.Start = start;
this.End = end;
}
public bool OverlapsWith(Meeting second)
{
return this.End > second.Start;
}
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
here are the results of that run as well
Did I miss anything?
Are there more edge cases that I didn't consider?
Is there a nice, neat, acceptable way of streamlining the foreach statements with the if statements inside of them? (Kind of curious if it is possible to one line it)
void Main()
? It's not a copy&paste yet ;-) \$\endgroup\$Main
. \$\endgroup\$