@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
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]); - не понимаю только это зачем

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

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

Войти через TM ID
Похожие вопросы
Digital Sharks Казань
от 60 000 до 65 000 руб.
CS Money Санкт-Петербург
от 120 000 до 150 000 руб.
Ingram Micro Cloud Москва
от 170 000 руб.