Qual è il modo migliore per convertire:
['a','b','c']
per:
{
0: 'a',
1: 'b',
2: 'c'
}
_.keyBy
(precedentemente _.indexBy
): lodash.com/docs#keyBy
_.toPlainObject
. Esempio:var myObj = _.toPlainObject(myArr)
Qual è il modo migliore per convertire:
['a','b','c']
per:
{
0: 'a',
1: 'b',
2: 'c'
}
_.keyBy
(precedentemente _.indexBy
): lodash.com/docs#keyBy
_.toPlainObject
. Esempio:var myObj = _.toPlainObject(myArr)
Risposte:
ECMAScript 6 introduce il polifillabile facilmente Object.assign
:
Il
Object.assign()
metodo viene utilizzato per copiare i valori di tutte le proprietà proprie enumerabili da uno o più oggetti di origine in un oggetto di destinazione. Restituirà l'oggetto di destinazione.
Object.assign({}, ['a','b','c']); // {0:"a", 1:"b", 2:"c"}
La length
proprietà propria dell'array non viene copiata perché non è enumerabile.
Inoltre, è possibile utilizzare la sintassi di diffusione ES6 per ottenere lo stesso risultato:
{ ...['a', 'b', 'c'] }
{ ...[sortedArray]}
Con una funzione come questa:
function toObject(arr) {
var rv = {};
for (var i = 0; i < arr.length; ++i)
rv[i] = arr[i];
return rv;
}
L'array è già più o meno solo un oggetto, ma gli array hanno un comportamento "interessante" e speciale rispetto alle proprietà con nome intero. Quanto sopra ti darà un oggetto semplice.
modifica oh anche potresti voler tenere conto di "buchi" nella matrice:
function toObject(arr) {
var rv = {};
for (var i = 0; i < arr.length; ++i)
if (arr[i] !== undefined) rv[i] = arr[i];
return rv;
}
Nei runtime JavaScript moderni, è possibile utilizzare il .reduce()
metodo:
var obj = arr.reduce(function(acc, cur, i) {
acc[i] = cur;
return acc;
}, {});
Quello evita anche "buchi" nell'array, perché è così che .reduce()
funziona.
[]
) se non si usano chiavi di proprietà numeriche e la proprietà "length".
const obj = arr.reduce((obj, cur, i) => { return { ...obj, [i]: cur }; }, {});
const obj = arr.reduce((obj, cur, i) => ({ ...obj, [i]: cur }), {});
Potresti usare un accumulatore aka reduce
.
['a','b','c'].reduce(function(result, item, index, array) {
result[index] = item; //a, b, c
return result;
}, {}) //watch out the empty {}, which is passed as "result"
Passa un oggetto vuoto {}
come punto di partenza; quindi "aumenta" quell'oggetto in modo incrementale. Alla fine delle iterazioni, result
sarà{"0": "a", "1": "b", "2": "c"}
Se l'array è un insieme di oggetti coppia chiave-valore:
[{ a: 1},{ b: 2},{ c: 3}].reduce(function(result, item) {
var key = Object.keys(item)[0]; //first property: a, b, c
result[key] = item[key];
return result;
}, {});
produrrà: {a: 1, b: 2, c: 3}
Per completezza, reduceRight
consente di scorrere sull'array in ordine inverso:
[{ a: 1},{ b: 2},{ c: 3}].reduceRight(/* same implementation as above */)
produrrà: {c:3, b:2, a:1}
Il tuo accumulatore può essere di qualsiasi tipo per uno scopo specifico. Ad esempio, per scambiare la chiave e il valore dell'oggetto in un array, passare []
:
[{ a: 1},{ b: 2},{ c: 3}].reduce(function(result, item, index) {
var key = Object.keys(item)[0]; //first property: a, b, c
var value = item[key];
var obj = {};
obj[value] = key;
result.push(obj);
return result;
}, []); //an empty array
produrrà: [{1: "a"}, {2: "b"}, {3: "c"}]
Diversamente map
, reduce
non può essere usato come mapping 1-1. Hai il pieno controllo degli articoli che desideri includere o escludere. Pertanto reduce
ti consente di ottenere ciò che filter
fa, il che rende reduce
molto versatile:
[{ a: 1},{ b: 2},{ c: 3}].reduce(function(result, item, index) {
if(index !== 0) { //skip the first item
result.push(item);
}
return result;
}, []); //an empty array
produrrà: [{2: "b"}, {3: "c"}]
Attenzione : reduce
e Object.key
fanno parte di ECMA 5th edition
; dovresti fornire un polyfill per i browser che non li supportano (in particolare IE8).
Vedi un'implementazione predefinita di Mozilla .
Se stai usando jquery:
$.extend({}, ['a', 'b', 'c']);
{0: 'a', 1: 'b', 2: 'c'}
ciò che è un risultato previsto.
Per completezza, diffusione ECMAScript 2015 (ES6). Richiederà un transpiler (Babel) o un ambiente con almeno ES6.
console.log(
{ ...['a', 'b', 'c'] }
)
Probabilmente lo scriverei in questo modo (poiché molto raramente non avrò la libreria underscorejs a portata di mano):
var _ = require('underscore');
var a = [ 'a', 'b', 'c' ];
var obj = _.extend({}, a);
console.log(obj);
// prints { '0': 'a', '1': 'b', '2': 'c' }
obj=_.extend({},a);
farebbe il lavoro. Inoltre, se stai ripetendo le matrici, direi che _.each
sarebbe più appropriato di _.map
. Tutto sommato, questa non è una buona risposta su più livelli.
Ecco un metodo O (1) ES2015 solo per completezza.
var arr = [1, 2, 3, 4, 5]; // array, already an object
Object.setPrototypeOf(arr, Object.prototype); // now no longer an array, still an object
length
proprietà. (3) L'oggetto è ancora un array, Array.isArray(arr) === true
. (4) I comportamenti speciali dell'array non vengono rimossi, ad esempio arr.length = 0
rimuove tutti gli indici. (5) Pertanto, penso che Object.assign
sia molto meglio .
Array.isArray
sta tornando true
per "l'oggetto" qui, anche se instanceof Array
non ...
Sorpreso di non vedere -
console.log(
Object.assign({}, ['a', 'b', 'c'])
)
{ "first":"a", "second":"b","third":"c" }
con le chiavi riparate - Sto cercando un distrutto
possiamo usare Object.assign
e array.reduce
funzione per convertire una matrice in oggetto.
var arr = [{a:{b:1}},{c:{d:2}}]
var newObj = arr.reduce((a, b) => Object.assign(a, b), {})
console.log(newObj)
Ho finito per usare l'operatore di diffusione degli oggetti, poiché fa parte dello standard ECMAScript 2015 (ES6).
const array = ['a', 'b', 'c'];
console.log({...array});
// it outputs {0:'a', 1:'b', 2:'c'}
Fatto il seguente violino come esempio.
Object.assign({}, ['one', 'two']); // {0: 'one', 1: 'two'}
Un modo semplice nel moderno JavaScript è quello di utilizzare Object.assign()
solo la copia della chiave: valore da un oggetto a un altro. Nel nostro caso, Array
dona proprietà a nuove {}
.
O.assign
quanto riguarda ma mancava di spiegazione. Oggi distruggere la matrice in oggetto è un modo ( {...array}
)
Per ES2016, dividere l'operatore per gli oggetti. Nota: questo è dopo ES6 e quindi il transpiler dovrà essere modificato.
const arr = ['a', 'b', 'c'];
const obj = {...arr}; // -> {0: "a", 1: "b", 2: "c"}
Cinque anni dopo, c'è un buon modo :)
Object.assign
è stato introdotto in ECMAScript 2015.
Object.assign({}, ['a', 'b', 'c'])
// {'0':'a', '1':'b', '2':'c'}
Usando javascript#forEach
uno si può fare questo
var result = {},
attributes = ['a', 'b','c'];
attributes.forEach(function(prop,index) {
result[index] = prop;
});
Con ECMA6:
attributes.forEach((prop,index)=>result[index] = prop);
FWIW, un altro approccio recente è quello di utilizzare il nuovo Object.fromEntries
insieme Object.entries
come segue:
const arr = ['a','b','c'];
arr[-2] = 'd';
arr.hello = 'e';
arr.length = 17;
const obj = Object.fromEntries(Object.entries(arr));
... che consente di evitare la memorizzazione di elementi di array sparsi come undefined
o null
e conserva chiavi non indice (es. numeri interi non positivi / non numerici).
Si potrebbe desiderare di aggiungere arr.length
, tuttavia, poiché ciò non è incluso:
obj.length = arr.length;
puoi usare l'operatore spread
x = [1,2,3,10]
{...x} // {0:1, 1:2, 2:3, 3:10}
Se stai usando ES6, puoi usare Object.assign e l'operatore spread
{ ...['a', 'b', 'c'] }
Se hai array nidificato come
var arr=[[1,2,3,4]]
Object.assign(...arr.map(d => ({[d[0]]: d[1]})))
new Map([['key1', 'value1'], ['key2', 'value2']]);
Uno veloce e sporco:
var obj = {},
arr = ['a','b','c'],
l = arr.length;
while( l && (obj[--l] = arr.pop() ) ){};
{0:"c", 1:"b", 2:"a"}
. O vuoi unshift
invece di pop
(o meglio) iniziare con i=arr.length-1
e decrementare invece.
l = arr.length
, e poi while (l && (obj[--l] = arr.pop())){}
(mi rendo conto che questo è vecchio, ma perché non semplificarlo ulteriormente).
Veloce e sporco # 2:
var i = 0
, s = {}
, a = ['A', 'B', 'C'];
while( a[i] ) { s[i] = a[i++] };
i < a.length
invece di a[i]
.
A partire da Lodash 3.0.0 è possibile utilizzare _.toPlainObject
var obj = _.toPlainObject(['a', 'b', 'c']);
console.log(obj);
<script src="https://cdn.jsdelivr.net/lodash/4.16.4/lodash.min.js"></script>
Ecco una funzione ricorsiva che ho appena scritto. È semplice e funziona bene.
// Convert array to object
var convArrToObj = function(array){
var thisEleObj = new Object();
if(typeof array == "object"){
for(var i in array){
var thisEle = convArrToObj(array[i]);
thisEleObj[i] = thisEle;
}
}else {
thisEleObj = array;
}
return thisEleObj;
}
Ecco un esempio ( jsFiddle ):
var array = new Array();
array.a = 123;
array.b = 234;
array.c = 345;
var array2 = new Array();
array2.a = 321;
array2.b = 432;
array2.c = 543;
var array3 = new Array();
array3.a = 132;
array3.b = 243;
array3.c = 354;
var array4 = new Array();
array4.a = 312;
array4.b = 423;
array4.c = 534;
var array5 = new Array();
array5.a = 112;
array5.b = 223;
array5.c = 334;
array.d = array2;
array4.d = array5;
array3.d = array4;
array.e = array3;
console.log(array);
// Convert array to object
var convArrToObj = function(array){
var thisEleObj = new Object();
if(typeof array == "object"){
for(var i in array){
var thisEle = convArrToObj(array[i]);
thisEleObj[i] = thisEle;
}
}else {
thisEleObj = array;
}
return thisEleObj;
}
console.log(convArrToObj(array));
risultati:
['a' = '1', 'b' = '2', 'c' = '3']
e lo vuoi in {a: 1, b: 2, c: 3}
questo modo funziona perfettamente.
.reduce((o,v,i)=>(o[i]=v,o), {})
[doc]
o più prolisso
var trAr2Obj = function (arr) {return arr.reduce((o,v,i)=>(o[i]=v,o), {});}
o
var transposeAr2Obj = arr=>arr.reduce((o,v,i)=>(o[i]=v,o), {})
uno più corto con JS alla vaniglia
JSON.stringify([["a", "X"], ["b", "Y"]].reduce((o,v,i)=>{return o[i]=v,o}, {}))
=> "{"0":["a","X"],"1":["b","Y"]}"
qualche esempio più complesso
[["a", "X"], ["b", "Y"]].reduce((o,v,i)=>{return o[v[0]]=v.slice(1)[0],o}, {})
=> Object {a: "X", b: "Y"}
ancora più breve (usando function(e) {console.log(e); return e;}
=== (e)=>(console.log(e),e)
)
nodejs
> [[1, 2, 3], [3,4,5]].reduce((o,v,i)=>(o[v[0]]=v.slice(1),o), {})
{ '1': [ 2, 3 ], '3': [ 4, 5 ] }
[/ Docs]
[/docs]
? Sarebbe più utile rendere eseguibili gli snippet di codice.
Lo farei semplicemente con Array.of()
. La matrice di ha la capacità di usare il suo contesto come costruttore.
NOTA 2 La funzione of è un metodo di fabbrica intenzionalmente generico; non richiede che questo valore sia il costruttore della matrice. Pertanto può essere trasferito o ereditato da altri costruttori che possono essere chiamati con un singolo argomento numerico.
Quindi potremmo legarci Array.of()
a una funzione e generare un array come un oggetto.
function dummy(){};
var thingy = Array.of.apply(dummy,[1,2,3,4]);
console.log(thingy);
Utilizzando Array.of()
uno si può anche fare una sottoclasse degli array .
Se puoi usare Map
o Object.assign
, è molto semplice.
Crea un array:
const languages = ['css', 'javascript', 'php', 'html'];
Di seguito viene creato un oggetto con indice come chiavi:
Object.assign({}, languages)
Replica lo stesso come sopra con Maps
Converte in un oggetto basato su indice {0 : 'css'}
ecc ...
const indexMap = new Map(languages.map((name, i) => [i, name] ));
indexMap.get(1) // javascript
Converti in un oggetto basato sul valore, {css : 'css is great'}
ecc ...
const valueMap = new Map(languages.map(name => [name, `${name} is great!`] ));
valueMap.get('css') // css is great
Un metodo semplice e sfacciato per convertire rapidamente una matrice di oggetti in un oggetto
function arrayToObject( srcArray ){
return JSON.parse( JSON.stringify( srcArray ) );
}
Quindi usandolo così ...
var p = [0,2,3,'pork','pie',6];
obj = new arrayToObject( p );
console.log( obj[3], obj[4] )
// expecting `pork pie`
Produzione:
pork pie
Verifica del tipo:
typeof obj
"object"
E le cose non sarebbero complete se non ci fosse un metodo prototipo
Array.prototype.toObject =function(){
return JSON.parse( JSON.stringify( this ) );
}
Usando come:
var q = [0,2,3,'cheese','whizz',6];
obj = q.toObject();
console.log( obj[3], obj[4] )
// expecting `cheese whizz`
Produzione:
cheese whizz
* NOTA che non esiste una routine di denominazione, quindi se si desidera avere nomi specifici, sarà necessario continuare a utilizzare i metodi esistenti di seguito.
Metodo precedente
Ciò consente di generare da un array un oggetto con le chiavi definite nell'ordine desiderato.
Array.prototype.toObject = function(keys){
var obj = {};
var tmp = this; // we want the original array intact.
if(keys.length == this.length){
var c = this.length-1;
while( c>=0 ){
obj[ keys[ c ] ] = tmp[c];
c--;
}
}
return obj;
};
result = ["cheese","paint",14,8].toObject([0,"onion",4,99]);
console.log(">>> :" + result.onion);
produrrà "paint", la funzione deve avere matrici di uguale lunghezza o si ottiene un oggetto vuoto.
Ecco un metodo aggiornato
Array.prototype.toObject = function(keys){
var obj = {};
if( keys.length == this.length)
while( keys.length )
obj[ keys.pop() ] = this[ keys.length ];
return obj;
};
let i = 0;
let myArray = ["first", "second", "third", "fourth"];
const arrayToObject = (arr) =>
Object.assign({}, ...arr.map(item => ({[i++]: item})));
console.log(arrayToObject(myArray));
Oppure usa
myArray = ["first", "second", "third", "fourth"]
console.log({...myArray})
ES5 - Soluzione:
Utilizzando la funzione prototipo di array 'push' e 'apply' è possibile popolare l'oggetto con gli elementi array.
var arr = ['a','b','c'];
var obj = new Object();
Array.prototype.push.apply(obj, arr);
console.log(obj); // { '0': 'a', '1': 'b', '2': 'c', length: 3 }
console.log(obj[2]); // c
{ name: a, div :b, salary:c}
Più browser supportati e un modo più flessibile per farlo è utilizzare un normale ciclo , qualcosa come:
const arr = ['a', 'b', 'c'],
obj = {};
for (let i=0; i<arr.length; i++) {
obj[i] = arr[i];
}
Ma anche il modo moderno potrebbe essere l'utilizzo dell'operatore di diffusione , come:
{...arr}
O assegnazione oggetto :
Object.assign({}, ['a', 'b', 'c']);
Entrambi torneranno :
{0: "a", 1: "b", 2: "c"}
È possibile utilizzare una funzione come questa:
var toObject = function(array) {
var o = {};
for (var property in array) {
if (String(property >>> 0) == property && property >>> 0 != 0xffffffff) {
o[i] = array[i];
}
}
return o;
};
Questo dovrebbe gestire array sparsi in modo più efficiente.
Ecco una soluzione in coffeescript
arrayToObj = (arr) ->
obj = {}
for v,i in arr
obj[i] = v if v?
obj
obj[i] = v for v,i in arr when v?