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