2017-10-11 4 views
1

Ich versuche, zwei Arrays zu kombinieren. Jedes dieser Arrays verfügt über untergeordnete Arrays, die Bereiche definieren. Ich möchte es so kombinieren, dass das neue Array die neuen Bereiche basierend auf den Werten in den beiden Arrays wiedergibt. Beispiel:Kombinieren Sie zwei Arrays mit Bereichen

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

Könnten Sie Ihren Code schreiben? –

+0

Sind die Serien garantiert bestellt? Auch ja, bitte posten Sie was Sie versucht haben. – Damon

+0

Ja. Sie müssen bestellt werden. Ich habe versucht, eine Switch-Case-Anweisung zu machen, und es wurde unhandlich. Das hat also nicht funktioniert. Ich versuche einen anderen Ansatz. Ich werde es bald posten. Danke Jungs – Poora

Antwort

0

Diese Lösung funktioniert auch, wenn die Bereiche nicht perfekt geordnet und nicht überlappen.

  1. Kombinieren beiden Listen zu einem Array von Arrays
  2. Flatten das Array von Arrays in eine einfache Anordnung von Zahlen
  3. entfernen die Duplikate aus dem Array (jede Zahl mit Ausnahme des ersten und letzten zweimal enthalten, so wir brauchen die)
  4. Schleife über den abgeflachten und dedupliziert Array
  5. Finden Sie den Index des min val zu beheben dann aus dem Array
  6. hinzufügen, dass min val auf einen „temp_range“, dass min val entfernen repräsentieren die Einzel Bereich
  7. Wenn die Länge des „temp_range“ jetzt zwei ist, dass wir dies zu unserer letzten Reihe von Bereichen hinzufügen, dann hat die temp_range mit der aktuellen min val beginnen


 

 
    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

Das ist großartig. Genau das, was ich brauchte. Vielen Dank – Poora

1

Sie könnten alle Werte in einem Objekt sammeln, sortieren und Tupel daraus erstellen.

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

Während mir der andere funktionalere Ansatz gefallen hat, gefiel mir nicht die Tatsache, dass er auf Nebenwirkungen angewiesen war, wo Dinge definiert wurden. Hier ist eine Version, die das ein wenig verbessert.

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

Ein generischer Ansatz flacht zunächst die verketteten Bereich Listen, geht zum anderes für eine sortierte und einzigartige Variante dieser Liste Bereich Indizes und zuletzt eine Liste von Tupeln Bereich von ihm erzeugt. Es hängt also nicht von irgendeiner Entfernungsreihenfolge ab und/oder ist agnostisch bezüglich Bereichsüberschneidungen.

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