- Я определяю
task
как (то, что имеет дату start
и end
дату) - I переопределить
event
как нечто, чтопроизошло: задание началось или закончилось
Что вы можете сделать, это путешествовать по t и соответственно отсортировать события (будь то начало задания, но также и завершение задания)
Рассмотрим следующую временную шкалу
---------------->t
O----X
O-----X
O------------X
Где O обозначает начальное задание, а X обозначает окончание
Это очень похоже на проверку правильности вашего HTML: Если вы сталкиваетесьоткрывающий тег, но в настоящее время открытого тега нет, значит, у вас есть пробел.
Таким образом, алгоритм будет таким:
events = []
forall tasks as start, end:
events.push({start: true, at: start}, {start:false, at:end})
sort the events as:
first by t time
in case two events have the same t,
opening events should come before closing ones
forall events:
when a start task:
if openTagCounter == 0 //and different than init
gaps.push(lastClosedAt, task.start)
openTagCounter++
when a end task:
openTagCounter--
if openTagCounter == 0
lastClosedAt = task.end
Вы можете обработать возможный пробел в начале и наначало
if startDay < events[0].start
gaps.push(guess what)
if last(events).end < endDay
gaps.push(same)
function getGaps(startDay, endDay, tasks){
let events = tasks.flatMap(t=>{
return [{ref: t, at: t.start, start:true},{ref: t, at: t.end, start:false}]
},[]);
events.sort((a,b)=>{
if(a.at!=b.at) return a.at-b.at;
return a.start?-1:0;
});
let gaps = [];
let lastClosed = 0;//lastClosed only truthy if start of a gap
let anyOpened = 0;
events.forEach(ev=>{
if(ev.start){
anyOpened++;
if(lastClosed){
gaps.push({start: lastClosed, end: ev.at});
lastClosed = false;
}
}else{
anyOpened--;
if(anyOpened == 0){
lastClosed = ev.at;
}
}
});
//finally handle the first gap, and the last gap
if(startDay != events[0].at){
gaps.push({start: startDay, end: events[0].at})
}
if(endDay != events[events.length-1].at){
gaps.push({start: events[events.length-1].at, end: endDay})
}
return gaps;
}
console.log(getGaps(0, 24, [
{start:23, end:23.5},
{start:23, end:24},
]))
//[ { start: 0, end: 23 } ]
console.log(getGaps(0, 24, [
{start:23, end:24},
{start:23, end:23.5},
]))
//[ { start: 0, end: 23 } ]
console.log(getGaps(0, 24, [
{start:23, end:23.7},
{start:23, end:23.5},
]))
//[ { start: 0, end: 23 }, { start: 23.7, end: 24 } ]
console.log(getGaps(0, 24, [
{start:23, end:23.5},
{start:23.5, end:23.7},
{start:23, end:23.5},
{start:23.5, end:23.7},
]))
//[ { start: 0, end: 23 }, { start: 23.7, end: 24 } ]