@daima

Как объединить массивы?

Есть массив интервалов, надо объединить перекрывающиеся, т.е:

[[0, 33],[66, 80]] => [[0, 33],[66, 80]]

[[0, 33],[66, 80],[0, 66],[33, 100]] => [0,100]

Накидал код:

const data = [
        [0, 33],
        [66, 80],
        [0, 66],
        [33, 100]
      ];

      createDataForSlider = data =>
        data.reduce((prevVal, time) => {
          let isPrevValUpdated = false;

          const timeStart = time[0];
          const timeEnd = time[1];

          /* eslint no-param-reassign: ["error", { "ignorePropertyModificationsFor": ["prevVal"] }] */
          if (prevVal.length) {
            for (let i = 0, ii = prevVal.length; i < ii; i += 1) {
              let prevValCurrent = prevVal[i];

              if (timeStart >= prevValCurrent[0] && timeEnd <= prevValCurrent[1]) {
                isPrevValUpdated = true;
                break;
              }
              if (
                !isPrevValUpdated &&
                timeStart >= prevValCurrent[0] &&
                timeStart <= prevValCurrent[1]
              ) {
                prevValCurrent[1] = timeEnd;
                isPrevValUpdated = true;
                break;
              }
              if (
                !isPrevValUpdated &&
                timeEnd >= prevValCurrent[0] &&
                timeEnd <= prevValCurrent[1]
              ) {
                prevValCurrent[0] = timeStart;
                isPrevValUpdated = true;
                break;
              }

              //console.log("prevVal-", prevVal);
            }
          }
          if (!isPrevValUpdated) {
            prevVal.push([timeStart, timeEnd]);
          }
          return prevVal;
        }, []);

      createDataForSlider(data);


На выходе имею [[0, 100], [66, 80]]. Это потому что сперва диапазон [[0, 33]], потом [[0, 33],[66, 80]], потом [[0, 66], [66, 80]], потом [[0, 100], [66, 80]] как бы проверять и остальные диапазоны без зацикливания
  • Вопрос задан
  • 112 просмотров
Решения вопроса 1
0xD34F
@0xD34F Куратор тега JavaScript
function mergeIntervals(intervals) {
  intervals = intervals.map(n => [...n]);

  if (intervals.length < 2) {
    return intervals;
  }

  intervals.sort((a, b) => a[0] - b[0]);

  const stack = [ intervals.shift() ];

  intervals.forEach(n => {
    const top = stack[stack.length - 1];

    if (top[1] < n[0]) {
      stack.push(n);
    } else if (top[1] < n[1]) {
      top[1] = n[1];
    }
  });

  return stack;
}


UPD. Вынесено из комментариев:

intervals = intervals.map(n => [...n]); - не понимаю только это зачем

Это копирование переданного в функцию массива, чтобы не испортить оригинал - так как выполняется сортировка, удаление нулевого элемента, изменение верхних границ интервалов.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы
от 30 000 до 65 000 руб.
от 60 000 до 90 000 руб.
BSSL Москва
от 50 000 до 150 000 руб.
22 июл. 2019, в 08:24
100000 руб./за проект
22 июл. 2019, в 07:20
3000 руб./за проект
22 июл. 2019, в 07:13
150000 руб./за проект