2013-02-27 3 views
8

Ich würde Element-weise mehrere Arrays hinzufügen. Das heißt, ich habe mehrere Arrays gleicher Länge, und ich würde nur eine mit der gleichen Anzahl von Elementen, die die Summe der Eingänge sind, benötigen. Underscore verfügt über Methoden, um alle Elemente zu einem zusammenzufassen und jedes Element mit einer Funktion abzubilden, aber ich finde keine Möglichkeit, zwei Arrays stückweise zu kombinieren.Mapping zwei (oder mehr) Arrays in eine mit Unterstreichung.js

Wenn meine ursprünglichen Arrays waren [1,2,3,4,5,6], [1,1,1,1,1,1] und [2,2,2,2,2,2] das Ergebnis sollte [4,5,6,7,8,9] sein.

Ich weiß, ich kann es tun, indem ich über die Arrays iterieren, aber frage mich, ob es einfacher/schneller wäre, die Funktionen von underscore.js zu verwenden. Kann ich es schaffen? Wie?

Antwort

10

Leichter ja, schneller nein. Um eine zipWith zu emulieren, können Sie eine zip mit einem Summen- kombinieren reduce:

var arrays = [[1,2,3,4,5,6], [1,1,1,1,1,1], [2,2,2,2,2,2]]; 

_.map(_.zip.apply(_, arrays), function(pieces) { 
    return _.reduce(pieces, function(m, p) {return m+p;}, 0); 
}); 
+0

Das ist perfekt. Es funktioniert in allen meinen Szenarien und ist schnell genug. Ich werde es mit direkter Iteration vergleichen, sieht aber gut aus. Vielen Dank. –

+0

@Bergi Ich verstehe nicht die 'apply (_,' Notation. Zu welcher Unterstreichung Funktion ist dies _ bezogen auf? –

+0

@StephaneRolland: '_' Hier ist das Underscore-Objekt selbst. Überprüfen Sie, was ['fn.apply'] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply) macht mit den Argumenten ... Eigentlich hätten wir auch hier 'null' übergeben können. – Bergi

5

Ich denke nicht, dass es mit Unterstrich einfacher wäre. Hier sind zwei Optionen:

var a = [1,2,3,4,5,6] 
    , b = [1,1,1,1,1,1] 
    , c = [2,2,2,2,2,2]; 

var result = a.map(function(_,i) { 
    return a[i] + b[i] + c[i]; 
}); 

// OR 

var result = []; 
for (var i = 0; i < a.length; i++) { 
    result.push(a[i] + b[i] + c[i]); 
} 

console.log(result); //=> [4,5,6,7,8,9] 
+1

Die zweite Version ist, was ich gerade benutze. Das einzige Problem ist, dass, obwohl es für zwei oder drei Arrays funktioniert, es konzeptionell begrenzt ist, wenn es ein paar mehr gibt. Meine ursprüngliche Idee war es, ein Array von Arrays zu erstellen und sie irgendwie elementweise zuzuordnen. Wie auch immer, Ihre erste Lösung sieht vielversprechend aus. Ich werde versuchen, es zu verlängern. –

0

Sie können zip in Verbindung mit Karte verwenden und reduzieren: Nicht getestet, aber so etwas wie dies funktionieren könnte

var result = _.map(_.zip(array1, array2, array3),function(zipped){return _.reduce(zipped, function(memo, num){ return memo + num; }, 0)}); 
+0

Da ist ein fehlender Punkt nach dem ersten Unterstrich :). Ihre Lösung ist fast die gleiche, die Bergi schrieb, aber mit Zip Vs. zip._apply gibt mir keine richtigen Antworten. Ich muss zurück zur Dokumentation gehen, um den Grund zu finden. Ich danke dir sehr. –

+0

Ich korrigiere das. – benzonico

3

Sie könnten lodash (https://lodash.com/) statt Unterstrich verwenden, der einen ziemlich coolen zipWith (https://lodash.com/docs#zipWith) Operator hat, der wie das folgende Beispiel funktioniert. (Anmerkung _.add ist auch eine lodash Mathematikfunktion)

var a = [1,2,3,4,5,6] 
    , b = [1,1,1,1,1,1] 
    , c = [2,2,2,2,2,2]; 

var result = _.zipWith(a, b, c, _.add); 

// result = [4, 5, 6, 7, 8, 9]