繁体   English   中英

如何合并间距数组

[英]How to merge spacing arrays

有一个间隔数组,有必要合并重叠部分,即:

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

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

编写代码。 我得到结果[[0,100],[66,80]]。 这是因为首先是范围[[0,33]],然后是[[0,33],[66,80]],然后是[[0,66],[66,80]],然后是[[0,100 ],[66,80]]好像检查其他范围而不循环

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);

尝试跟随

  1. 根据所有开始时间对数组进行排序
  2. 现在,通过将以前插入的频率与当前频率进行比较,使用空数组累加器来降低它。

     const frequencies = [[0, 33], [66, 80], [0, 66], [33, 100]]; const sortedFrequencies = frequencies.sort((f1, f2) =>{ return f1[0] - f2[0]}); sortedFrequencies.reduce((acc, current) => { if(acc.length > 0 && current[0] <= acc[acc.length - 1][1]) { acc[acc.length - 1][1] = current[1] > acc[acc.length - 1][1] ? current[1] : acc[acc.length - 1][1]; } else { acc.push(current) } return acc; }, []); 

您需要先对输入数组进行排序,如下所示:

data.sort((val1, val2) => {
  //order by range start ASC
  let res1 = val1[0] - val2[0];

  if (res1 === 0) {
    //order by range end DESC
    return val2[1] - val1[1];
  }

  return res1;
});

然后它应该工作。

您可以对数组进行排序(开始ASC,结束DESC),并检查开始和结束位置是否在另一个数据集的范围内,然后返回带有最小值和最大值的新集合。 否则,取原始值。

 function merge(array) { return array .sort((a, b) => a[0] - b[0] || b[1] - a[1]) .reduce((t, [l, r]) => { var item = [[l, r]]; if (!t) return [[l, r]]; return t .map(([a, b]) => l <= a && a <= r || l <= b && b <= r || a <= l && l <= b || a <= r && r <= b ? (item = [], [Math.min(a, l), Math.max(b, r)]) : [a, b] ) .concat(item); }, undefined); } console.log(merge([[0, 33], [66, 80], [0, 66], [33, 100]])); console.log(merge([[0, 33], [66, 80]])); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

要合并重叠的1-D数组,.sort()将根据元素1上每个1-D数组的值按升序对2-D数组进行排序。然后,您可以循环遍历每个元素-已排序的2-D数组的1和检查索引i处的元素是否是索引i + 1元素的子集。如果是,则将索引i + 1的元素推到新数组。

function isSubSet(a, b) {
    if ((a[0] >= b[0] && a[1] <= b[1]) ||
        (a[0] <= b[0] && a[1] >= b[1])) {
        return true;
    } else {
        return false;
    }
}

function mergeArray(arr) {

    let newArr = [];

    for (let i = 0; i < arr.length - 1; i++) {
        if (isSubSet(arr[i], arr[i + 1])) {
            newArr.push(arr[i + 1]);
        }
    }

    return newArr;
}

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

let arr = mergeArray(data.sort());

一次又一次地循环遍历,直到输出数组的长度等于输入数组的长度。

如果在一个回合之后有一些重叠的地方,则下一回合将把两者合并,并且输出会更短。

当然,该过程将以少于data.lenght个步骤的速度停止。

从运行时间的角度来看,这可能不是最有效的方法,但是如果这不是问题,我会去解决。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM