Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将一组重叠范围划分为一组非重叠范围_Javascript_Set_Intervals_Overlapping_Range - Fatal编程技术网

Javascript 将一组重叠范围划分为一组非重叠范围

Javascript 将一组重叠范围划分为一组非重叠范围,javascript,set,intervals,overlapping,range,Javascript,Set,Intervals,Overlapping,Range,我有一系列重叠的范围: var ranges = [{ "from": 0, "to": 100 }, { "from": 50, "to": 200 }, { "from": 0, "to": 100 }, { "from": 70, "to": 200 }, { "from": 90, "to": 300 }]; 我需要将它转换成一组不重叠的范围,即。e、 : var nonOverlapping = spli

我有一系列重叠的范围:

var ranges = [{
    "from": 0,
    "to": 100
}, {
    "from": 50,
    "to": 200
}, {
    "from": 0,
    "to": 100
}, {
    "from": 70,
    "to": 200
}, {
    "from": 90,
    "to": 300
}];
我需要将它转换成一组不重叠的范围,即。e、 :

var nonOverlapping = splitRanges(ranges);

/*
nonOverlapping = [{
    "from": 0,
    "to": 49
}, {
    "from": 50,
    "to": 69
}, {
    "from": 70,
    "to": 89
}, {
    "from": 90,
    "to": 100
}, {
    "from": 101,
    "to": 200
}, {
    "from": 201,
    "to": 300
}]
*/
我制作了一个函数来实现这一点(用JavaScript),但正如您所看到的,它的运行速度非常慢,因为它使用了所谓的“幼稚方法”:

预期产出为:

[{
    "id": 3,
    "from": 90,
    "to": 100
}, {
    "id": 4,
    "from": 90,
    "to": 100
}, {
    "id": 4,
    "from": 101,
    "to": 300
}, {
    "id": 1,
    "from": 0,
    "to": 29
}, {
    "id": 1,
    "from": 90,
    "to": 100
}, {
    "id": 3,
    "from": 0,
    "to": 29
}, {
    "id": 1,
    "from": 30,
    "to": 30
}, {
    "id": 1,
    "from": 31,
    "to": 89
}, {
    "id": 2,
    "from": 30,
    "to": 30
}, {
    "id": 3,
    "from": 30,
    "to": 30
}, {
    "id": 3,
    "from": 31,
    "to": 89
}]

这将为指定的输入生成所需的结果:

function splitRanges (intervals) { 'use strict';
  // Create arrays of the from and to values, do not record duplicate values 
  for (var to = [], from = [], n, i = intervals.length; i--;) {
    if (to.indexOf (n = intervals[i].to) < 0)
      to.push (n);
    if (from.indexOf (n = intervals[i].from) < 0)
      from.push (n);
  }

  // Sort both arrays
  to.sort (function (a, b) { return a-b; });
  from.sort (function (a, b) { return a-b; });

  // Create new intervals array
  intervals = [];
  while (to.length)
    intervals.push ({
      from: from.shift (),
      to: from.length == 0 ? (from.push ((n = to.shift ()) + 1), n) :
          from[0] > to[0] ? from[1] - 1 : from[0] - 1
    });

  return intervals;
}  
函数拆分范围(间隔){‘使用严格’;
//创建from和to值的数组,不要记录重复的值
for(var to=[],from=[],n,i=interval.length;i--;){
if(to.indexOf(n=区间[i].to)<0)
to.push(n);
if(from.indexOf(n=区间[i].from)<0)
from.push(n);
}
//对两个数组进行排序
to.sort(函数(a,b){返回a-b;});
from.sort(函数(a,b){返回a-b;});
//创建新的间隔数组
间隔=[];
while(到.长度)
推({
from:from.shift(),
to:from.length==0?(from.push((n=to.shift())+1),n):
从[0]>到[0]?从[1]-1:从[0]-1
});
返回间隔;
}  

当相同的数字同时显示为from和to值时,则会产生“伪”空范围。不知道这种情况是否会发生在您的数据中,或者额外的范围是否是一个问题

这就是问题所在,因为算法应该能够处理(从===到)可以添加到示例中的范围1)从60到60的空间隔,2)从200到230的另一个范围并更新您的预期结果是,请看原始问题的最后一部分,我在下面的“编辑”中放置了一个示例,范围为30..30,以及我的非最佳解决方案产生的预期结果。刚过一个范围数组(如我的问题描述)进入文本区域并按下“拆分!”按钮,第二个文本区域将包含拆分结果。所以这正是我需要的,我需要它如何工作,只是更快。希望这有帮助:任何优化的版本。?
[{
    "id": 3,
    "from": 90,
    "to": 100
}, {
    "id": 4,
    "from": 90,
    "to": 100
}, {
    "id": 4,
    "from": 101,
    "to": 300
}, {
    "id": 1,
    "from": 0,
    "to": 29
}, {
    "id": 1,
    "from": 90,
    "to": 100
}, {
    "id": 3,
    "from": 0,
    "to": 29
}, {
    "id": 1,
    "from": 30,
    "to": 30
}, {
    "id": 1,
    "from": 31,
    "to": 89
}, {
    "id": 2,
    "from": 30,
    "to": 30
}, {
    "id": 3,
    "from": 30,
    "to": 30
}, {
    "id": 3,
    "from": 31,
    "to": 89
}]
function splitRanges (intervals) { 'use strict';
  // Create arrays of the from and to values, do not record duplicate values 
  for (var to = [], from = [], n, i = intervals.length; i--;) {
    if (to.indexOf (n = intervals[i].to) < 0)
      to.push (n);
    if (from.indexOf (n = intervals[i].from) < 0)
      from.push (n);
  }

  // Sort both arrays
  to.sort (function (a, b) { return a-b; });
  from.sort (function (a, b) { return a-b; });

  // Create new intervals array
  intervals = [];
  while (to.length)
    intervals.push ({
      from: from.shift (),
      to: from.length == 0 ? (from.push ((n = to.shift ()) + 1), n) :
          from[0] > to[0] ? from[1] - 1 : from[0] - 1
    });

  return intervals;
}