@lemonlimelike

Как склеить интервалы?

Всем привет! Есть такая задача написать метод для того чтобы склеить интервалы.
У меня есть метод, который делает обратное, т.е. разделяет интервалы.
Но вот как склеить эти интервалы?

Метод для разделения:
private function getFreeInterval($intervals, $startTime, $endTime): array
    {
        $result = [];
        foreach($intervals as $key => $interval){
            list($start, $end) = explode('-', $interval);
            if ($startTime >= $start && $endTime <= $end) {
                if ($startTime > $start) {
                    $result[] = "{$start}-{$startTime}";
                }
                if ($endTime < $end) {
                    $result[] = "{$endTime}-{$end}";
                }

            } else {
                $result[] = $interval;
            }
        }

        return $result;
    }


Этот методы принимает интервал времени ['08:00:00','12:30:00'] и начало и конец, допустим $startTime = "10:30:00" и $endTime = "11:15:00"
И тогда я получу вот что: ["08:00:00-09:45:00", "11:15:00-12:00:00"]

Если я передам этот новый массив интервалов и такие StartTime и EndTime: $startTime = "08:30:00" && $endTime = "09:15:00", то вот что получаю
["08:00:00-07:45:00", "09:15:00-09:45:00", "11:15:00-12:00:00"]

То есть этот метод работает отлично, и все правильно выводит.
А как сделать обратное?

Вот опять же, допустим есть метод getInterval(), который принимает массив интервалов и startTime и endTime. Такой массив
["08:00:00-07:45:00", "09:15:00-09:45:00", "11:15:00-12:00:00"]

и такой startTime $startTime = "08:30:00" && $endTime = "09:15:00" и вот нужно получить такой массив ["08:00:00-09:45:00", "11:15:00-12:00:00"]

Возможно ли такое?
  • Вопрос задан
  • 105 просмотров
Решения вопроса 1
@Fallenyasha
Суть задачи в объединении пересечающихся интервалов, по сути достаточно взять два массива диапазонов, объединить их, отсортировать по возрастанию по начальной дате и пробежаться циклом сравнивая конец текущего с началом следующего, если больше, то объединить.

Напишу схематично:
var data = concat(array1, array2).sort(e => e.startTime);
for (var i = 0; i < data.length-1;)
{
  if (data[i].endTime >= data[i+1].startTime)
  {
    data[i].endTime = max(data[i].endTime, data[i+1].endTime);
    remove(data[i+1]);
  }
  else
    i++;
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы