【问题标题】:Merge overlaping objects with interval properties in array with javascript使用javascript在数组中合并具有间隔属性的重叠对象
【发布时间】:2017-02-02 20:29:05
【问题描述】:

我发现了类似的问题,但批准的答案不适用于我的问题。

我有一个输入:范围对象数组,每个对象包含:

  • start:整数,范围的开始,
  • end:整数,范围结束。

输出应该是:

覆盖与输入相同范围的非重叠范围对象数组,按从最小开始到最大开始的顺序排列。如果满足以下条件,则两个范围不重叠:

  • range1.start <= range2.start
  • range1.end >= range2.start

输入:

[
  { start: 8, end: 10 },
  { start: 5, end: 7  },
  { start: 9, end: 12 },
  { start: 2, end: 6  },
]

输出:

 [
   { start: 2, end: 7  },
   { start: 8, end: 12 }
 ]

正如我所提到的,我尝试在网络上应用解决方案来合并重叠间隔,但它们没有完成这项工作。

谢谢。

【问题讨论】:

    标签: javascript arrays object


    【解决方案1】:

    您可以按startend 对数组进行排序,并通过检查范围是否重叠来迭代排序后的数组。

    var data = [{ start: 8, end: 10 }, { start: 5, end: 7 }, { start: 9, end: 12 }, { start: 2, end: 6 }],
        result = data
            .sort(function (a, b) { return a.start - b.start || a.end - b.end; })
            .reduce(function (r, a) {
                var last = r[r.length - 1] || [];
                if (last.start <= a.start && a.start <= last.end) {
                    if (last.end < a.end) {
                        last.end = a.end;
                    }
                    return r;
                }
                return r.concat(a);
            }, []);
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

      【解决方案2】:

      var ranges = [
        { start: 8, end: 10 },
        { start: 5, end: 7  },
        { start: 9, end: 12 },
        { start: 2, end: 6  }
      ];
      
      
      function merge(ranges) {
        // first, sort the ranges
        ranges.sort((a, b) => a.start - b.start);
        
        // take two ranges, and merges them together
        var mergeFn = (a, b) => ({start: Math.min(a.start, b.start), end: Math.max(a.end, b.end)});
        
        // check if two ranges overlap
        var overlapFn = (a, b) => (b.start <= a.end);
        
        // make current the first item of the array (start the array from 1 to not check the first item against itself)
        var current = ranges[0];
        var result = [];
        for(var i = 1; i < ranges.length; i++) {
          if(overlapFn(current, ranges[i])) // if the current range overlapping with this range
             current = mergeFn(current, ranges[i]); // merge them into the current range
          else { // if not
            result.push(current); // add the current accumulated range as result
            current = ranges[i]; // start accumulating another one from this range
          }
        }
        result.push(current); // add the last result
      
        return result;
      }
      
      console.log(merge(ranges));

      【讨论】:

      • 谢谢你,易卜拉欣。由于某种原因,您提供的代码对我不起作用(我正在处理的页面上的验证器无法识别 a 和 b)但我看到您的代码在这里有效。我使用了 Nina 的代码,它成功了。谢谢。
      • 不客气!也许您的浏览器不支持 箭头函数(假设您的代码是供浏览器使用的)。
      猜你喜欢
      • 2021-03-29
      • 2015-12-16
      • 2015-12-14
      • 1970-01-01
      • 2015-12-05
      • 1970-01-01
      • 2019-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多