2013-02-27 14 views
8

Avrei bisogno di aggiungere diversi array di elementi. Cioè, ho diversi array di uguale lunghezza, e avrei bisogno solo di uno con lo stesso numero di elementi che sono la somma degli input. Underscore ha dei metodi per piegare tutti gli elementi in uno e per mappare ogni elemento usando una funzione, ma non riesco a trovare alcun modo per combinare due array in modo saggio.Mappare due (o più) matrici in uno con underscore.js

Se i miei array originali erano [1,2,3,4,5,6], [1,1,1,1,1,1] e [2,2,2,2,2,2] il risultato dovrebbe essere [4,5,6,7,8,9].

So che posso farlo iterando sugli array, ma mi chiedo se sarebbe più facile/più veloce utilizzando le funzioni underscore.js. Posso farlo? Come?

risposta

10

Più facile sì, più veloce no. Per emulare un zipWith, è possibile combinare un zip con un sinottiche 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

È perfetto. Funziona in tutti i miei scenari ed è abbastanza veloce. Ho intenzione di confrontarlo con l'iterazione diretta, ma sembra fantastico. Grazie. –

+0

@Bergi Non capisco il 'apply (_,' notation. A quale funzione underscorejs è questa _ relativa a? –

+0

@StephaneRolland: '_' ecco l'oggetto Underscore stesso. Controlla cosa [' fn.apply'] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply) fa con gli argomenti ... In realtà potremmo aver passato anche 'null' qui. – Bergi

5

Non penso che sarebbe più facile con underscore. Ecco due opzioni:

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

La seconda versione è ciò che sto usando in questo momento. L'unico problema è che, mentre funziona bene per due o tre array, è concettualmente limitato quando ce ne sono altri. La mia idea originale era di costruire una serie di array e, in qualche modo, mapparli tutti in base agli elementi. Ad ogni modo, la tua prima soluzione sembra promettente. Cercherò di estenderlo. –

0

È possibile utilizzare zip in combinazione con la mappa e ridurre: Non testato, ma qualcosa di simile potrebbe funzionare

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

C'è un punto mancante dopo il primo trattino basso :). La tua soluzione è quasi la stessa Bergi ha scritto, ma utilizzando zip Vs. zip._apply non mi dà risposte corrette. Ho bisogno di tornare alla documentazione per trovare il perché. Grazie mille. –

+0

L'ho corretto. – benzonico

3

Potresti usare lodash (https://lodash.com/) invece di underscore che ha un ottimo zipWith (https://lodash.com/docs#zipWith) operatore che funzionerebbe come nell'esempio qui sotto. (nota _.add è anche una funzione di matematica di lodash)

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] 
Problemi correlati