我正在尝试组合两个数组。每个阵列都有子阵列,用于定义范围。我想将它组合起来,以便创建的新数组根据两个数组中的值反映新范围。例如:
//I would like to create a new array based on the ranges in a and b.
var a = [[0, 20], [20, 40], [40, 70]];
var b = [[10, 25], [25, 35]]
//The result reflects the new ranges based on values in both the arrays.
var result = [[0, 10], [10, 20], [20, 25], [25, 35], [35, 40], [40, 70]]
答案 0 :(得分:1)
您可以收集对象中的所有值,对其进行排序并从中构建元组。
var a = [[0, 20], [20, 40], [40, 70]],
b = [[10, 25], [25, 35]],
values = Object.create(null),
result = [];
a.concat(b).forEach(function (a) {
values[a[0]] = true;
values[a[1]] = true;
});
Object
.keys(values)
.map(Number)
.sort(function (a, b) {
return a - b;
})
.reduce(function (a, b) {
result.push([a, b]);
return b;
});
console.log(result);

.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:0)
即使范围没有完全有序且不重叠,此解决方案也能正常工作。
var a = [[0, 20], [20, 40], [40, 70]];
var b = [[10, 15], [25, 35]]
var combined = a.concat(b);
var flattened = combined.reduce((a, b) => a.concat(b), []);
flattened = flattened.filter(function(item, pos) {
return flattened.indexOf(item) == pos;
});
var final_array = [];
var temp_range = [];
var minIdx = null;
var minVal = null;
while (flattened.length){
minIdx = flattened.indexOf(Math.min(...flattened));
minVal = flattened.splice(minIdx, 1)[0];
temp_range.push(minVal);
if(temp_range.length == 2){
final_array.push(temp_range);
temp_range = [minVal];
}
}
console.log(final_array);
答案 2 :(得分:0)
虽然我喜欢发布的其他更实用的方法,但我并不喜欢它依赖于定义事物的副作用这一事实。这是一个稍微改进的版本。
var a = [[0, 20], [20, 40], [40, 70]];
var b = [[10, 25], [25, 35]];
// Utility function for flattening the input arrays
var flatten = function flatten(arr) {
return arr.reduce(function(agg, arr) {
return agg.concat(Array.isArray(arr) ? flatten(arr) : arr);
}, []);
};
// Combine everything into a single flat list of numbers
var c = flatten(a.concat(b));
// Create a hash out of the values to get unique endpoints
var d = c.reduce(function(agg, n) {
agg[n] = true;
return agg;
}, {});
// Reduce the hash to the ranges
var [_, e] = Object.keys(d).map(Number).reduce(function([last, agg], n) {
if(last === null) return [n, agg];
agg.push([last, n]);
return [n, agg];
}, [null, []]);
console.log(e);

答案 3 :(得分:0)
更通用的方法首先展平连接范围列表,其次是这个范围索引列表的排序和唯一变体,最后从中生成范围元组列表。因此,它不依赖于任何范围顺序和/或与范围跨度碰撞无关。
function flatten(list) { // simplified variant
if (Array.isArray(list)) {
list = list.reduce(function (collector, elm) {
return collector.concat(flatten(elm));
}, []);
}
return list;
}
function unique(list) { // simplified variant
var i = -1, k, len = list.length, type;
while (++i < len) {
type = list[i];
k = i;
while ((i in list) && (++k < len)) {
if ((k in list) && (list[k] === type)) {
list.splice(k, 1);
--len;
--k;
}
}
}
return list;
}
var aRangeList = [[0, 20], [20, 40], [40, 70]];
var bRangeList = [[10, 25], [25, 35]];
var cRangeList = unique(
flatten(aRangeList.concat(bRangeList)).sort()
).reduce(function collectRangeTuple (collector, rangeIndex) {
var tuple = collector.recentTuple;
tuple.push(rangeIndex);
if (tuple.length >= 2) {
collector.rangeList.push(tuple);
collector.recentTuple = [rangeIndex];
}
return collector
}, { recentTuple: [], rangeList: [] }).rangeList;
console.log('aRangeList : ', aRangeList);
console.log('bRangeList : ', bRangeList);
console.log('cRangeList : ', cRangeList);
.as-console-wrapper { max-height: 100%!important; top: 0; }