2017-10-11 91 views
1

我想结合两个数组。每个数组都有定义范围的子数组。我想将它结合起来,以便创建的新数组反映基于两个数组中值的新范围。例如:结合两个数组与范围

//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

你能发布您的代码? –

+0

范围是否有保证?也是,请张贴你的企图。 – Damon

+0

是的。他们需要订购。我试着做一个switch case case,它很笨拙。所以这没有奏效。我正在尝试另一种方法。我会很快发布。谢谢你们 – Poora

回答

0

此解决方案,即使范围不完美有序的和非重叠的。

  1. 合并两个列表成阵列的一个阵列
  2. 拼合数组的数组编号的简单阵列
  3. 从阵列中删除重复(包括除了第一和最后一个的每个数量的两倍,从而我们需要修复)
  4. 环路扁平和去重复阵列
  5. 在查找分钟val的索引然后从该阵列
  6. 删除分钟VAL那分钟VAL添加到一个“temp_range”表示个别范围
  7. 如果“temp_range”的长度,现在是二,我们将它添加到我们的范围的最后一个数组,然后有temp_range开始与当前分钟VAL


 

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

+0

这太好了。正是我需要的。谢谢 – Poora

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

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

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