2015-06-30 18 views
20

ingresso Dato:Appiattire matrice con oggetti in oggetto 1

[{ a: 1 }, { b: 2 }, { c: 3 }] 

Come restituire:

{ a: 1, b: 2, c: 3 } 

Per gli array it's not a problem con lodash ma qui abbiamo matrice di oggetti.

+0

È anche ok chiedere su SO per i pacchetti npm? –

+0

No. Puoi descrivere il problema che stai avendo, come hai appena fatto, e se la risposta è "installa questo pacchetto npm" allora va bene; ma non dovresti chiedere specificamente un pacchetto per risolvere il problema. – JJJ

risposta

39

Uso Object.assign:

let merged = Object.assign(...arr); // ES6 (2015) syntax 

var merged = Object.assign.apply(Object, arr); // ES5 syntax 

Nota che Object.assign non è ancora implementata in molte ambiente e potrebbe essere necessario Polyfill esso (sia con core-js, un'altra polyfill o utilizzando il polyfill su MDN).

Lei ha parlato di lodash, quindi vale la pena sottolineare è dotato di una funzione di _.assign per questo scopo che fa la stessa cosa:

var merged = _.assign.apply(_, [{ a: 1 }, { b: 2 }, { c: 3 }]); 

Ma ho davvero consiglio il nuovo modo libreria standard.

+3

Soluzione molto bella! – nils

+3

Non dovresti fare 'Object.assign ({}, ... arr)' ?! – Bergi

+0

@Bergi Posso se voglio conservare l'input di 'assign' intatto. Io di certo non ce l'ho se non lo faccio. Dal momento che non era un requisito, non l'ho trattato come tale. –

4

Ecco una versione non utilizzando metodi ES6 ...

var arr = [{ a: 1 }, { b: 2 }, { c: 3 }]; 
var obj = {}; 

for(var i = 0; i < arr.length; i++) { 
    var o = arr[i]; 
    for(var key in o) { 
     if(typeof o[key] != 'function'){ 
      obj[key] = o[key]; 
     } 
    } 
} 

console.log(obj); 

violino: http://jsfiddle.net/yaw3wbb8/

+2

Si noti che questo copierà anche le proprietà del prototipo enumerabile (che non è un problema in questo caso particolare). –

+0

sarebbe un semplice '&&! O.propertyIsEnumerable (chiave)' aggiunto all'istruzione if risolvere questo? –

+0

Bene, per ... solo enumera le proprietà enumerabili. A 'Object (o) .hasOwnProperty (obj)' lo aggiusterà comunque (assicurandoci che non sia sul prototipo) - la parte 'Object (o)' è per garantire che non stiamo chiamando un metodo non esistente in modo che per esempio passare '4' non fallirebbe (e non copiare nulla). –

3

È possibile utilizzare la funzione underscore.extend così:

var _ = require('underscore'); 
var a = [{ a: 1 }, { b: 2 }, { c: 3 }]; 

var result = _.extend.apply(null, a); 
console.log(result); // { a: 1, b: 2, c: 3 } 
console.log(a); // [ { a: 1, b: 2, c: 3 }, { b: 2 }, { c: 3 } ] 

E per evitare di modificare l'array originale dovresti usare

var _ = require('underscore'); 
var a = [{ a: 1 }, { b: 2 }, { c: 3 }]; 

var result = _.extend.apply(null, [{}].concat(a)); 
console.log(result); // { a: 1, b: 2, c: 3 } 
console.log(a); // [ { a: 1 }, { b: 2 }, { c: 3 } ] 

Here can test it

1

Ho un po 'di soluzione chiara che non richiedono un polyfill.

var arr = [{ a: 1 }, { b: 2 }, { c: 3 }]; 
var object = {}; 

arr.map(function(obj){ 
    var prop = Object.getOwnPropertyNames(obj); 
    object[prop] = obj[prop]; 
}); 

Speranza che aiuta :)

+2

Non ho idea del motivo per cui è stato eseguito l'upvoted poiché non può non funzionare - getOwnPropertyNames restituisce un array. –

+0

@BenjaminGruenbaum Per questo caso d'uso funziona perfettamente. Vedi il mio violino: http://jsfiddle.net/dhgsbg99/ –

+1

Questo è solo secondario poiché tutti gli oggetti hanno una singola proprietà e 'toString' l'array con una singola proprietà dà lo stesso risultato, prova ad aggiungere una proprietà a uno di gli oggetti e vederlo fallire: http://jsfiddle.net/zqvhceyj/ –

4

Con lodash, è possibile utilizzare merge():

var arr = [ { a: 1 }, { b: 2 }, { c: 3 } ]; 
_.merge.apply(null, [{}].concat(arr)); 
// → { a: 1, b: 2, c: 3 } 

Se stai facendo questo in diversi luoghi, si può fare merge() un po 'più elegante, utilizzando partial() e :

var merge = _.spread(_.partial(_.merge, {})); 
merge(arr); 
// → { a: 1, b: 2, c: 3 }