假设有如许一个需求,一个数组的子元素满是有序数组,相似:
let arr= [[1, 2], [0, 3, 4,4,4,6,7,8,9,10], [-1, 4],[-1,3],[-1],[100,200],[5,1000,30000]];
我们愿望将上述数组兼并为一个有序数组,怎样处置惩罚呢?
最简朴的计划就是:
将数组团体兼并,然后sort排序,代码以下:
let ret=arr.reduce((arr1,arr2)=>arr1.concat(arr2)).sort((a,b)=>a-b);
ret=Array.from(new Set(ret));
console.log(ret);
然则上面的代码没有充分应用数组子元素自身就是有序数组这一特征,我们应用“合并排序”算法,能够大大的进步相似数组的兼并排序机能,代码(代码内里有细致解释)以下:
let arr= [[1, 2], [0, 3, 4,4,4,6,7,8,9,10], [-1, 4],[-1,3],[-1],[100,200],[5,1000,30000]];
// let arr= [[1,2,3]];
function merge(arr){
//纪录每一个数组轮回比较时的下标变化
function filterIndexArr() {
indexArr=indexArr.filter((item,index)=>{
return item.count<arr[item.index].length;
});
}
//将每次比较的元素放进一个暂时数组内里,掏出最小值放入ret
function pushToArr(arr) {
let minVal=arr[0].val;
let increaseArr=[arr[0].index];
arr.forEach((item,index)=>{
if (minVal>item.val){
minVal=item.val;
increaseArr=[item.index];
}else if (minVal==item.val && index!=0){
increaseArr.push(item.index)
}
});
increaseArr.forEach((item)=>{
let thatItem=item;
indexArr.forEach((item)=>{
if (item.index==thatItem){
item.count++;
}
});
});
filterIndexArr();
ret.push(minVal);
}
let ret=[];
let indexArr=arr.map((item,index)=>{
return {
index,
count:0
}
});
filterIndexArr();
let compareArr=[];
while (indexArr.length>1){
//轮回比较每一个数组的第一个元素
compareArr=indexArr.map((item,index)=>{
return {
index:item.index,
val:arr[item.index][item.count]
}
});
pushToArr(compareArr);
}
//掏出末了不需要比较的数组元素,直接拼接到ret背面
let remainArr=arr[indexArr[0].index].slice(indexArr[0].count);
ret=ret.concat(remainArr);
ret=Array.from(new Set(ret));
return ret;
}
let ret=merge(arr);
console.log(ret);
因为子数组自身有序,离别纪录要被比较数组的下标,轮回掏出最小值push到ret就能够了,是否是很简朴。