I have an algorithm that examines an array of Event (StartTime,EndTime) on a timeline that runs from Midnight->Midnight to check for any gaps. The algorithm works, but there is one configuration where it doesn't work.
Before I show the code, here's the specific case where it doesn't work: When I have a Midnight-ending Event with the same StartTime as another event which does not end at midnight. The problem here is that I add an erroneous GAP to my result, a GAP (Midnight,Midnight). It shouldn't be there in my result.
Now the code: All Events (including GAP Events) have a (StartTime,EndTime). I am receiving an incoming array of normal proposedEvents, and my job is to return a filled-out array of preparedGapEvents.
function schedulerPrepareGapEvents(proposedEvents) {
var preparedGapEvents = [];
// First sort proposed events by StartTime
proposedEvents.sort(sortObjectsByStartTime); // sort by StartTime of the event
// If there are no proposed events, exit immediately with an empty result
if (proposedEvents.length == 0) {
return preparedGapEvents;
}
// Manually add first gap, if it exists: Sorted Proposed Event #1 not starting at 12:00am
var startTimeFirst = getTimestampFromString(proposedEvents[0].startTime);
if (startTimeFirst > 0) {
preparedGapEvents.push({"gapEventID" : "event-GAP" + generateUniqueID(),
"gapEventColor" : globalGapEventColor,
"gapEventStartTimestamp" : 0,
"gapEventEndTimestamp" : startTimeFirst});
}
// Initially lastMaxEndTime is the End Time of 1st Event
var lastMaxEndTime = getTimestampFromString(proposedEvents[0].endTime);
// Main Event Traversal Loop
jQuery.each(proposedEvents, function(index, item) {
// Get the current proposed event's StartTime/EndTime in the loop
var startTimeCurrent = getTimestampFromString(item.startTime);
var endTimeCurrent = getTimestampFromString(item.endTime);
// Next neighboring proposed event
var nextEvent = proposedEvents[index+1];
// If Next Proposed Event exists
if (nextEvent != null) {
var startTimeNext = getTimestampFromString(nextEvent.startTime);
var endTimeNext = getTimestampFromString(nextEvent.endTime);
if (startTimeNext > lastMaxEndTime) { // Gap detected!
preparedGapEvents.push({"gapEventID" : "event-GAP" + generateUniqueID(),
"gapEventColor" : globalGapEventColor,
"gapEventStartTimestamp" : lastMaxEndTime,
"gapEventEndTimestamp" : startTimeNext});
}
// Keep track of the current MAX EndTime: either this new event's EndTime or the previous Max EndTime
lastMaxEndTime = Math.max(lastMaxEndTime, endTimeNext);
}
else {
// Last Proposed Event (no next neighbor): its End Time must be at the 24-hr END mark, otherwise a gap
if (endTimeCurrent < 1440) {
preparedGapEvents.push({"gapEventID" : "event-GAP" + generateUniqueID(),
"gapEventColor" : globalGapEventColor,
"gapEventStartTimestamp" : lastMaxEndTime,
"gapEventEndTimestamp" : 1440});
}
}
});
return preparedGapEvents;
The problem here is somewhere in the main loop. After I sort by StartTime, the two adjoining events can be either in Position 0 or 1, depending on chance. Suppose that by chance I have a neighbor in the +1 position that I will examine. In that case, I fall into the ELSE, and satisfy the condition if (endTimeCurrent < 1440) because that event's End Time is not 1440 (Midnight)!
So how do I fix this?
