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

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

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

Войти через центр авторизации
Похожие вопросы