2016-10-22 1 views
5

Ich habe 2 2D-ArraysJavascript - Summe 2d Arrays

var arr1 = [ 
    [1, 'a'], 
    [2, 'b'] 
] 

var arr2 = [ 
    [3, 'a'], 
    [5, 'c'] 
] 

Ich möchte diese zwei Arrays summieren dieses Ergebnis

var output = [ 
    [4, 'a'], 
    [2, 'b'], 
    [5, 'c'] 
] 

Ich habe versucht zu schreiben 2 .map Funktionen zu erhalten, aber zusammen mit dem gewünschten Ergebnisse das wird viele Duplikate zurückgeben:

function sumArrays (arr1, arr2) { 
    var output = []; 
    arr2.map(function(i) { 
    arr1.map(function(n) { 
     if (i[1] === n[1]) { 
     output.push([i[0] + n[0], i[1]]) 
     } else { 
     output.push(i) 
     } 
    }) 
    }) 
    return output; 
} 

Gibt es einen einfacheren Weg, dies zu tun, oder sho Muss ich nun alles außer dem höchsten Wert für eine bestimmte Saite entfernen?

Danke für die Hilfe.

+0

Möchten Sie ein neues Array mit dem kombinierten Ergebnis erhalten? –

+0

Ich muss die Summe beider Arrays zurückgeben. Ich kann das entweder tun, indem ich die bestehenden modifiziere oder eine neue zurückgebe. –

+0

Wäre einfacher mit einer Karte, wie in '{a: 4, b: 2, c: 5}' – adeneo

Antwort

3

Verwenden Sie bitte nicht Array#map, wenn Sie kein neues Array benötigen, das diese Methode zurückgibt.

Sie könnten eine Hash-Tabelle für das Inventar verwenden und überprüfen und aktualisieren arr2 mit Array#forEach.

Vorschlag, die arr1 für Updates verwendet

var arr1 = [[1, 'a'], [2, 'b']], 
 
    arr2 = [[3, 'a'], [5, 'c']], 
 
    inventory = Object.create(null); 
 

 
arr1.forEach(function (a) { 
 
    this[a[1]] = a; 
 
}, inventory); 
 

 
arr2.forEach(function (a) { 
 
    if (!this[a[1]]) { 
 
     this[a[1]] = [0, a[1]]; 
 
     arr1.push(this[a[1]]); 
 
    } 
 
    this[a[1]][0] += a[0]; 
 
}, inventory); 
 

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

Vorschlag mit neuen Array für result.

var arr1 = [[1, 'a'], [2, 'b']], 
 
    arr2 = [[3, 'a'], [5, 'c']], 
 
    inventory = Object.create(null), 
 
    result = arr1.map(function (a) { 
 
     return this[a[1]] = [a[0], a[1]]; 
 
    }, inventory); 
 

 
arr2.forEach(function (a) { 
 
    if (!this[a[1]]) { 
 
     this[a[1]] = [0, a[1]]; 
 
     result.push(this[a[1]]); 
 
    } 
 
    this[a[1]][0] += a[0]; 
 
}, inventory); 
 

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

+2

Netter Trick mit der Konsole – zer00ne

+0

Gute Erklärung. Aber das erwartete Ergebnis ist ein Array. Warum also kein Array? –

+0

@PraneshRavi, das Ergebnis ist ein Array, wo siehst du kein Array? –

0

Diese Frage ist im Wesentlichen die gleiche wie this one, wo ich den gleichen ES6 Code vorgeschlagen, unter Verwendung von Hashes (Set) und eine Variante Code, die ich hier nicht wiederholen wird:

function sumArrays(a, b) { 
 
    return Array.from(
 
     b.reduce((m, [v,k]) => m.set(k, (m.get(k) || 0) + v), 
 
        new Map(a.map (([v,k]) => [k,v]))), // swap pairs 
 
     ([k,v]) => [v,k]) // swap back afterwards; 
 
} 
 

 
var arr1 = [ 
 
    [1, 'a'], 
 
    [2, 'b'] 
 
] 
 

 
var arr2 = [ 
 
    [3, 'a'], 
 
    [5, 'c'] 
 
] 
 

 
var result = sumArrays(arr1, arr2); 
 

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

0

Sie könnten auch diesen Witz tun h forEach() und findIndex().

var arr1 = [ 
 
    [1, 'a'], 
 
    [2, 'b'] 
 
] 
 

 
var arr2 = [ 
 
    [3, 'a'], 
 
    [5, 'c'] 
 
] 
 

 
function sumArrays(arr1, arr2) { 
 
    var r = arr1.slice(0); 
 
    arr2.forEach(function(e) { 
 
    var i = arr1.findIndex(function(a) { 
 
     return e[1] == a[1]; 
 
    }) 
 
    i != -1 ? r[i][0] += e[0] : r.push(e) 
 
    }) 
 
    return r; 
 
} 
 

 
console.log(sumArrays(arr1, arr2))

0

Concat beide Arrays, so dass Sie ein Array mit allen Tupeln haben.

Dann reduzieren diese Reihe von Tupeln, so dass alle kompatiblen Tupel angesammelt werden.

arr1.concat(arr2).reduce(function r(accumulator, iterand) { 

    // base case: no tuples in accumulator 
    if (accumulator.length == 0) { 
     // add current tuple to our empty accumulator. 
     return [iterand]; 
    } 

    // first tuple in accumulator is compatible with the currently-inspected tuple 
    if (accumulator[0][1] == iterand[1]) { 
     // increment the count in the compatible tuple that already exists in the accumulator 
     return [[accumulator[0][0]+iterand[0], accumulator[0][1]]].concat(accumulator.slice(1)); 
    } 

    // currently-inspected tuple is not compatible with first tuple in accumulator. leave first tuple in accumulator unchanged. run the inductive case upon the remaining tuples in the accumulator. 
    return [accumulator[0]].concat(r(accumulator.slice(1), iterand)); 

}, []) 

Dies ist eine funktionale Lösung, die keine Ihrer vorhandenen Eingabedaten verändert.