我有一系列重叠范围:
var ranges = [{
"from": 0,
"to": 100
}, {
"from": 50,
"to": 200
}, {
"from": 0,
"to": 100
}, {
"from": 70,
"to": 200
}, {
"from": 90,
"to": 300
}];
我需要将它转换为一组非重叠范围,i。 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中)但当然你可以看到它工作得很慢,因为它使用了所谓的“天真的方法”:
function splitRanges(ranges) {
var repeat, length, i, j;
var rangeA, rangeB, intersection;
do {
repeat = false;
length = ranges.length;
for (i = 0; i < length; i++) {
rangeA = ranges[i];
for (j = i + 1; j < length; j++) {
rangeB = ranges[j];
if (isIntersectingRanges(rangeA, rangeB)) {
repeat = true;
ranges.splice(i, 1);
intersection = splitRange(rangeA, rangeB);
while (intersection.length) {
ranges.push(intersection.shift());
}
}
if (repeat) break;
}
if (repeat) break;
}
} while (repeat);
}
有人可以帮我重写一下吗,所以它的行为方式相同,并且比天真的方法更快吗?
修改
算法应该能够跟踪范围ID +正确处理从==到:
的范围var ranges = [{
id: 1,
from: 0,
to: 100
}, {
id: 2,
from: 30,
to: 30,
}, {
id: 3,
from: 0,
to: 100
}, {
id: 4,
from: 90,
to: 300
}];
预期输出为:
[{
"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
}]
答案 0 :(得分:1)
这会产生指定输入的所需结果:
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和a值时,会产生“虚假”的空范围。不知道这种情况是否会在您的数据中发生,或者额外的范围是否有问题