我正在使用Node.js. (...和underscore.js)
考虑这个数据结构
var numbers = [
[10, 20]
[30, 40]
[40, 50]
[45, 70]
... //Possibly more arrays (always contains two numbers)
]
numbers
包含始终包含数字对的数组。将这些数字对视为" start"和"结束"。我想要一个以numbers
为参数的函数,并循环其内容,如果" start"一对的数字重叠"结束"前一对的数量,这些数组合并为一个。例如:
var numbers = [
[10, 20]
[19, 40]
[40, 60]
[70, 80]
]
成为这个:
var numbers = [
[10, 60] // First, second and third array is merged because of overlapping .
[70, 80]
]
实际上,我已经为此编写了一个功能正常的功能,但感觉有点笨重。
我很好奇,如果一些javascript向导可以用超级优雅的解决方案让我眼花缭乱=)。
答案 0 :(得分:7)
创建一个空的“result”数组。循环遍历范围数组,并更改结果的最后一项或向其添加当前范围。
function merge(ranges) {
var result = [], last;
ranges.forEach(function (r) {
if (!last || r[0] > last[1])
result.push(last = r);
else if (r[1] > last[1])
last[1] = r[1];
});
return result;
}
r = [[10, 20], [19, 40], [40, 60], [70, 80]];
document.write(JSON.stringify(merge(r)));
这假设源数组已排序,如果情况并非总是如此,请在合并前对其进行排序:
ranges.sort(function(a, b) { return a[0]-b[0] || a[1]-b[1] });
答案 1 :(得分:5)
我创建了一个能够完成你想要的功能:
function merge(arr) {
// copy and sort the array
var result = arr.slice().sort(function(a, b) {
return a[0] > b[0];
}),
i = 0;
while(i < result.length - 1) {
var current = result[i],
next = result[i+1];
// check if there is an overlapping
if(current[1] >= next[0]) {
current[1] = Math.max(current[1], next[1]);
// remove next
result.splice(i+1, 1);
} else {
// move to next
i++;
}
}
return result;
};
此功能可以这种方式使用:
var mergedNumbers = merge(numbers);
的 DEMO 强>
答案 2 :(得分:2)
正如@Brett所说,这可能更适合Code Review(只需确保包含您当前的实现)。如果您在那里发帖,请在某处提及它,我会移动我的答案。
假设您的numbers
数组已经正确排序,此函数应该可以执行您想要的操作:
function combine(numbers) {
return numbers.reduce(function(combined, next) {
if (!combined.length || combined[combined.length-1][1] < next[0]) combined.push(next);
else {
var prev = combined.pop();
combined.push([prev[0], Math.max(prev[1], next[1])]);
}
return combined;
}, []);
}
var n = [[10, 20], [19, 40], [40, 60], [70, 80], [75, 76]];
var r = combine(n);
document.write('<pre>' + JSON.stringify(r) + '</pre>');
&#13;
这&#34; reduce
s&#34;使用reduce函数中的以下逻辑将原始数组添加到新数组:
push
当前项目将传递到combined
数组。pop
combined
数组中的最后一项。push
最后一项和当前项目的组合到combined
数组。答案 3 :(得分:1)
简单简洁的 JavaScript 解决方案:
算法
实现代码
var merge = (intervals) => {
intervals.sort((a, b) => a[0] - b[0]);
const merged = [intervals[0]];
for (let i = 1; i < intervals.length; i++) {
const [start, end] = intervals[i];
let prev = merged[merged.length - 1];
if (prev[1] >= start) {
prev[1] = Math.max(prev[1], end);
} else merged.push(intervals[i]);
}
return merged;
};
console.log(merge([[10, 20], [19, 40], [40, 60], [70, 80]]));