2017-10-11 10 views
1

2つの配列を結合しようとしています。それらの配列のそれぞれに、範囲を定義する子配列があります。私は新しい配列が2つの配列の値に基づいて新しい範囲を反映するようにそれを組み合わせたいと思います。例:範囲が2つの配列を結合する

//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文を実行しようとしましたが、扱いにくくなりました。それはうまくいきませんでした。私は別のアプローチを試みている。まもなく投稿します。ありがとうございました – Poora

答えて

0

このソリューションでは、範囲が完全に注文し、非重複していない場合でも動作します。

  1. 配列から重複を削除する数字
  2. の単純な配列に配列の配列を平らに(最初と最後を除く各数が二倍そう含まれるアレイ
  3. の配列に両方のリストを結合我々は表す「temp_range」にその分valを追加し、アレイ
  4. からその分valを削除分のvalのインデックスを検索し、平坦化し、重複排除配列
  5. 上)
  6. ループこれを修正する必要があります個々の範囲
  7. 「temp_range」の長さは、我々が範囲の最終的な配列にこれを追加し、今2である場合、その現在の分と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; }

関連する問題