Рассчитать перекрытия временных диапазонов с временным диапазоном - PullRequest
0 голосов
/ 06 ноября 2019

Я пытаюсь вычислить количество (в минутах) перекрытий между заданным временным диапазоном и массивом временных диапазонов.

Сначала я упорядочиваю диапазоны по времени начала и фильтрую их, если они не перекрываютсяс диапазоном.

const range = ["2019-11-06 08:00", "2019-11-06 17:00"]; // 9h
const ranges = [
  ["2019-11-06 00:00", "2019-11-06 10:00"],
  ["2019-11-06 22:00", "2019-11-06 24:00"],
  ["2019-11-06 09:00", "2019-11-06 12:00"]
]

function calculateOvelappings(range, ranges) {
  const start = moment(range[0])
  const end = moment(range[1])
  let overlaps = 0
  // order ranges by start time
  ranges = ranges.sort((a, b) => moment(a[0]).unix() - moment(b[0]).unix())
  for(let i = 0; i < ranges.length; i++) {
    const rangeStart = moment(ranges[i][0])
    const rangeEnd = moment(ranges[i][1])
    if (rangeEnd.isBefore(start) || rangeStart.isAfter(end)) {
      continue;
    }
    
  }
  return overlaps
}


console.log(calculateOvelappings(range, ranges))
<script src="https://cdn.jsdelivr.net/momentjs/2.14.1/moment-with-locales.min.js"></script>

РЕДАКТИРОВАТЬ

Правильный ответ для перекрытий будет 4 часа. Диапазон ввода начинается с 08:00 и пересекается с диапазоном 1 (из массива) до 10:00 (2 часа). Диапазон 2 не имеет значения. Диапазон 3 перекрывается с диапазоном ввода с 09:00 до 12:00, но с 09:00 до 10:00 уже рассчитан из диапазона 1. Поэтому 2 + (3 - 1) = 4 часа.

Существует ли элегантный алгоритм для расчета этого? Буду признателен за любую помощь, псевдокод или даже теоретический ответ.

Вот JsBin: https://jsbin.com/noyuhekura/1/edit?js,console

1 Ответ

0 голосов
/ 06 ноября 2019
const range = ["2019-11-06 08:00", "2019-11-06 17:00"]; // 9h
const ranges = [
  ["2019-11-06 00:00", "2019-11-06 10:00"],
  ["2019-11-06 22:00", "2019-11-06 24:00"],
  ["2019-11-06 09:00", "2019-11-06 12:00"]
]

function calculateOvelappings(range, ranges) {
  const start = moment(range[0])
  const end = moment(range[1])
  let overlaps = 0
  // order ranges by start time
  ranges = ranges.sort((a, b) => moment(a[0]).unix() - moment(b[0]).unix())
  for(let i = 0; i < ranges.length; i++) {
    const rangeStart = moment(ranges[i][0])
    const rangeEnd = moment(ranges[i][1])
    if (rangeEnd.isBefore(start) || rangeStart.isAfter(end)) {
      continue;
    }
    overlaps += rangeEnd - rangeStart // Updated
  }
  return overlaps
}


console.log(calculateOvelappings(range, ranges))

...