Converter Matriz para Objeto

Qual é a melhor maneira de converter:

['a','b','c'] 

para:

 { 0: 'a', 1: 'b', 2: 'c' } 

Com uma function como esta:

 function toObject(arr) { var rv = {}; for (var i = 0; i < arr.length; ++i) rv[i] = arr[i]; return rv; } 

Sua matriz já é mais ou menos apenas um object, mas as matrizes têm um comportamento "interessante" e especial em relação às propriedades de nome inteiro. O acima lhe dará um object simples.

edite oh também você pode querer considerar "buracos" na matriz:

 function toObject(arr) { var rv = {}; for (var i = 0; i < arr.length; ++i) if (arr[i] !== undefined) rv[i] = arr[i]; return rv; } 

Nos tempos de execução JavaScript modernos, você pode usar o método .reduce() :

 var obj = arr.reduce(function(acc, cur, i) { acc[i] = cur; return acc; }, {}); 

Aquele também evita "buracos" no array, porque é assim que .reduce() funciona.

Você poderia usar um acumulador 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" 

Passar um object vazio {} como ponto de partida; então “aumenta” esse object incrementalmente. No final das iterações, o result será {"0": "a", "1": "b", "2": "c"}

Se sua matriz for um conjunto de objects de pares de valor-chave:

 [{ 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; }, {}); 

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

Por uma questão de reduceRight , o reduceRight permite que você faça a iteração de seu array na ordem inversa:

 [{ a: 1},{ b: 2},{ c: 3}].reduceRight(/* same implementation as above */) 

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

Seu acumulador pode ser de qualquer tipo para seu propósito específico. Por exemplo, para trocar a chave e o valor do seu object em um array, passe [] :

 [{ 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 

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

Ao contrário do map , a reduce não pode ser usada como um mapeamento 1-1. Você tem controle total sobre os itens que deseja include ou excluir. Portanto, reduce permite que você atinja o que o filter faz, o que torna a reduce muito versátil:

 [{ 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 

produzirá: [{2: "b"}, {3: "c"}]

Cuidado : reduce e Object.key fazem parte da ECMA 5th edition do ECMA 5th edition ; você deve fornecer um polyfill para navegadores que não os suportam (principalmente o IE8).

Veja uma implementação padrão pelo Mozilla .

O ECMAScript 6 introduz o Object.assign facilmente Object.assign :

O método Object.assign() é usado para copiar os valores de todas as propriedades próprias enumeráveis ​​de um ou mais objects de origem para um object de destino. Ele retornará o object de destino.

 Object.assign({}, ['a','b','c']); // {0:"a", 1:"b", 2:"c"} 

A propriedade de length próprio da matriz não é copiada porque não é enumerável.

Se você estiver usando jquery:

 $.extend({}, ['a', 'b', 'c']); 

Eu provavelmente escreveria desse jeito (já que muito raramente eu não terei a biblioteca underscorejs disponível):

 var _ = require('underscore'); var a = [ 'a', 'b', 'c' ]; var obj = _.extend({}, a); console.log(obj); // prints { '0': 'a', '1': 'b', '2': 'c' } 

Para completar, o ECMAScript 2015 (ES6) está se espalhando. Exigirá um transpilador (Babel) ou um ambiente executando pelo menos ES6.

 { ...['a', 'b', 'c'] } 

Aqui está um método O (1) ES2015 apenas para completar.

 var arr = [1, 2, 3, 4, 5]; // array, already an object Object.setPrototypeOf(arr, Object.prototype); // now no longer an array, still an object 

Surpreende não ver –

 Object.assign({}, your_array) 
 Object.assign({}, ['one', 'two']); // {0: 'one', 1: 'two'} 

Object.assign() fácil no JavaScript moderno é usar Object.assign() que não faz nada além de copiar key: value de um object para outro. No nosso caso, o Array doa propriedades para o novo {} .

Acabei usando o operador de propagação de objects, já que faz parte do padrão ECMAScript 2015 (ES6).

 const array = ['a', 'b', 'c']; console.log({...array}); // it outputs {0:'a', 1:'b', 2:'c'} 

Fiz o seguinte violino como um exemplo.

Cinco anos depois, há um bom caminho 🙂

Object.assign foi introduzido no ECMAScript 2015.

 Object.assign({}, ['a', 'b', 'c']) // {'0':'a', '1':'b', '2':'c'} 

você pode usar o operador de spread

 x = [1,2,3,10] {...x} // {0:1, 1:2, 2:3, 3:10} 

Podemos usar a function array.reduce e array.reduce para converter uma matriz em object.

 var arr = [{a:{b:1}},{c:{d:2}}] var newObj = arr.reduce((a, b) => Object.assign(a, b), {}) console.log(newObj) 

Um rápido e sujo:

 var obj = {}, arr = ['a','b','c'], l = arr.length; while( l && (obj[--l] = arr.pop() ) ){}; 

A partir do Lodash 3.0.0 você pode usar o _.toPlainObject

 var obj = _.toPlainObject(['a', 'b', 'c']); console.log(obj); 
  

Rápido e sujo # 2:

 var i = 0 , s = {} , a = ['A', 'B', 'C']; while( a[i] ) { s[i] = a[i++] }; 

Eu faria isso simplesmente com Array.of() . Array of tem a capacidade de usar seu contexto como um construtor.

NOTA 2 A function é um método de fábrica intencionalmente genérico; não requer que este valor seja o construtor Array. Portanto, ele pode ser transferido ou herdado por outros construtores que podem ser chamados com um único argumento numérico.

Portanto, podemos vincular Array.of() a uma function e gerar um array como object.

 function dummy(){}; var thingy = Array.of.apply(dummy,[1,2,3,4]); console.log(thingy); 

Se você estiver usando o ES6, poderá usar o Object.assign e o operador de spread

 { ...['a', 'b', 'c'] } 

Se você tem matriz aninhada como

 var arr=[[1,2,3,4]] Object.assign(...arr.map(d => ({[d[0]]: d[1]}))) 

Aqui está uma solução em coffeescript

 arrayToObj = (arr) -> obj = {} for v,i in arr obj[i] = v if v? obj 

Isso permite que você gere de uma matriz um object com chaves que você define na ordem desejada.

 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); vai produzir “pintura”, a function tem que ter matrizes de igual comprimento ou você recebe um object vazio.

Aqui está um método atualizado

 Array.prototype.toObject = function(keys){ var obj = {}; if( keys.length == this.length) while( keys.length ) obj[ keys.pop() ] = this[ keys.length ]; return obj; }; 

Aqui está uma function recursiva que acabei de escrever. É simples e funciona bem.

 // 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; } 

Aqui está um exemplo ( 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)); 

Resultados: Matriz Recursiva para Objeto

Se você estiver usando angularjs você pode usar angular.extend, o mesmo efeito com $ .extend de jquery.

 var newObj = {}; angular.extend(newObj, ['a','b','c']); 
 .reduce((o,v,i)=>(o[i]=v,o), {}) 

[docs]

ou mais detalhado

 var trAr2Obj = function (arr) {return arr.reduce((o,v,i)=>(o[i]=v,o), {});} 

ou

 var transposeAr2Obj = arr=>arr.reduce((o,v,i)=>(o[i]=v,o), {}) 

mais curto um com baunilha JS

 JSON.stringify([["a", "X"], ["b", "Y"]].reduce((o,v,i)=>{return o[i]=v,o}, {})) => "{"0":["a","X"],"1":["b","Y"]}" 

algum exemplo mais complexo

 [["a", "X"], ["b", "Y"]].reduce((o,v,i)=>{return o[v[0]]=v.slice(1)[0],o}, {}) => Object {a: "X", b: "Y"} 

ainda mais curto (usando a 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]

Se você pode usar Map ou Object.assign , é muito fácil.

Crie uma matriz:

 const languages = ['css', 'javascript', 'php', 'html']; 

O abaixo cria um object com índice como chaves:

 Object.assign({}, languages) 

Replicar o mesmo que acima com o Maps

Converte em um object baseado em índice {0 : 'css'} etc …

 const indexMap = new Map(languages.map((name, i) => [i, name] )); indexMap.get(1) // javascript 

Converter para um object baseado em valor {css : 'css is great'} etc …

 const valueMap = new Map(languages.map(name => [name, `${name} is great!`] )); valueMap.get('css') // css is great 

Você poderia usar uma function como esta:

 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; }; 

Este deve lidar com matrizes esparsas com mais eficiência.

Não é diretamente relevante, mas eu vim aqui procurando por um forro para mesclar objects nesteds, como

 const nodes = { node1: { interfaces: {if1: {}, if2: {}} }, node2: { interfaces: {if3: {}, if4: {}} }, node3: { interfaces: {if5: {}, if6: {}} }, } 

A solução é usar uma combinação de redução e difusão de objects:

 const allInterfaces = nodes => Object.keys(nodes).reduce((res, key) => ({...res, ...nodes[key].interfaces}), {}) 
 let i = 0; let myArray = ["first", "second", "third", "fourth"]; const arrayToObject = (arr) => Object.assign({}, ...arr.map(item => ({[i++]: item}))); console.log(arrayToObject(myArray)); 

usando javascript você pode fazer isso para cada

 var result = {}, attributes = ['a', 'b','c']; attributes.forEach(function(prop,index) { result[index] = prop; }); 

Com o ECMA6:

 attributes.forEach((prop,index)=>result[index] = prop); 

Eu enfrentei esse problema várias vezes e decidi escrever uma function que é tão genérica quanto possível. Dê uma olhada e sinta-se à vontade para modificar qualquer coisa

 function typeOf(obj) { if ( typeof(obj) == 'object' ) { if (obj.length) return 'array'; else return 'object'; } else return typeof(obj); } function objToArray(obj, ignoreKeys) { var arr = []; if (typeOf(obj) == 'object') { for (var key in obj) { if (typeOf(obj[key]) == 'object') { if (ignoreKeys) arr.push(objToArray(obj[key],ignoreKeys)); else arr.push([key,objToArray(obj[key])]); } else arr.push(obj[key]); } }else if (typeOf(obj) == 'array') { for (var key=0;key 

Eu usaria sublinhado para isso, mas se isso não estiver disponível, então eu iria cair para baixo usando o reduzir com um valor inicial de object vazio {}

 >>> ['a', 'b', 'c'].reduce(function(p, c, i) {p[i] = c; return p}, {}) Object { 0="a", 1="b", 2="c"} 

reduzir deve estar amplamente disponível na maioria dos navegadores hoje, veja MDN