2014-11-11 7 views
5

sto trasformando questo array di oggetti:Sottolineatura: matrice di oggetti su oggetto piatto. Qual è la magia?

[ 
    { 
    first: { 
     blah: 1, 
     baz: 2 
    } 
    }, 
    { 
    second: { 
     foo: 1, 
     bar: 2 
    } 
    } 
] 

Per questo semplice oggetto piatto:

{ 
    first: { 
    blah: 1, 
    baz: 2 
    }, 
    second: { 
    foo: 1, 
    bar: 2 
    } 
} 

I due modi più semplici che ho trovato per farlo usando sottolineatura/LoDash sono:

// Using reduce and extend 
_.reduce(myArray, _.extend) 

// Using assign and apply 
_.assign.apply(_, myArray); 

Il codice completo è documentato in un JSBin: http://jsbin.com/kovuhu/1/edit?js,console

Ho letto molta documentazione su apply/bind/call/assign/reduce/extend ... Ma non riesco a capire cosa stia realmente succedendo dietro le tende.

Qualcuno può aiutarmi a capire il segreto dei trucchi magici che entrambi questi one-liner eseguono?

+0

Eseguono magia oscura, poiché * mutano * il primo dei tuoi oggetti. Dovrebbe essere '_.reduce (myArray, _.extend, {}) '(che desugars bene per' estendere ({}, myArray [0]), myArray [1]) ') – Bergi

risposta

2

reduce accetta tutti i valori in un array/proprietà in un oggetto e aggregates them. In questo caso, extend viene passato a reduce, ovvero stai passando un valore function(a,b) per l'estensione del valore a (riportato a ogni passaggio) con tutte le proprietà dell'oggetto b (ogni valore nell'array, uno alla volta). In one liner, reduce di sottolineatura avvicina dell'array, iniziando con un oggetto {}, e semplicemente discariche tutte le proprietà dell'elemento array in tale oggetto come cammina lungo l'array di input. In JS pianura sarebbe qualcosa di simile:

var thing = {}; 
var deeparray = [{...}, {...}, {...}]; 
deeparray.forEach(function(v) { 
    Object.keys(v).forEach(function(k) { 
    thing[k] = v[k]; 
    } 
}); 
return thing; 

assign (not found in underscore) fa la stessa cosa, prendendo un array di oggetti e li schiacciando insieme. È letteralmente l'unica cosa che fa. La chiamata _assign.apply(_, myArray) è lo stesso _ chiamare this.assign(myArray)-apply è una base funzione JavaScript per chiamare una funzione mentre "escludere manualmente" che cosa significa la parola this dentro quella funzione. _.assign.apply(_,myArray) è lo stesso di chiamare _.assing(myArray) se non con la garanzia ha aggiunto che this sarà lodash, e non qualche funzione random ambito contesto.

+0

Grazie, ora capisco cosa sta succedendo con' reduce' e 'estendi'. Non sono sicuro di comprendere appieno perché _.assign (myArray) non funzionerebbe e abbiamo bisogno di sovrascrivere il 'this' con' _'. Puoi ampliarlo? – Kaelig

+1

la funzione è internamente vincolata da un diverso ambito, quindi se non si utilizza 'apply'," this "si riferisce allo scope della funzione di livello superiore, da quello che posso vedere nella fonte. –

4

Per capire questo, facciamo una semplice versione di assign (alias extend). Accetteremo solo un argomento, che chiameremo fonte, e lo aggiungeremo al nostro risultato.

function assign(result, source) { 

    var keys = Object.keys(source), 
    length = keys.length; 

    for (var i=0 ; i < length; i ++) { 
    var key = keys[i]; 
    result[key] = source[key]; 
    } 

    return result; 
} 

Ora rompiamo l'ingresso in pezzi:

var a = { 
    first: { 
    blah: 1, 
    baz: 2 
    } 
} 

var b = { 
    second: { 
    foo: 1, 
    bar: 2 
    } 
} 

var input = [a, b]; 

Ora possiamo chiamare ridurre:

_.reduce(input, assign); 

ridurre chiamerò assegnare due volte:

assign(result, a); 
// assigns the (key, value) pair ("first", {blah: 1, baz: 2}) to result 

assign(result, b); 
// assigns the (key, value) pair ("second", {foo: 1, bar: 2}) to result 

Talk è a buon mercato, mi mostra il codice: http://jsbin.com/hexiza/3/edit?js,console

È possibile visualizzare l'assegnazione viene implementata utilizzando createAssigner() e baseAssign() nello Lo-Dash source code.

+0

Grazie Andrew per aver mostrato ancora un altro modo di fare la stessa cosa (ridurre + assegnare). L'esempio è molto chiaro. – Kaelig

Problemi correlati