Por algum motivo, não consigo encontrar essa coisa simples nos documentos MDN (talvez eu esteja apenas perdendo).
Eu esperava que isso funcionasse:
const map = new Map({foo: 'bar'});
map.get('foo'); // 'bar'
... mas a primeira linha joga TypeError: (var)[Symbol.iterator] is not a function
Como faço um mapa de um objeto simples? Eu realmente preciso primeiro convertê-lo em uma matriz de matrizes de pares de valores-chave?
javascript
ecmascript-6
callum
fonte
fonte
Object.entries
realmente é a melhor abordagemObject.keys
, e a abordagem da função geradora de bergi é ligeiramente mais direta do queObject.keys
ouObject.entries
.Respostas:
Sim, o
Map
construtor usa uma matriz de pares de valores-chave.Object.entries
é um novo método estático do objeto disponível no ES2017 (19.1.2.5) .Atualmente está implementado no Firefox 46+ e Edge 14+ e em versões mais recentes do Chrome
Se você precisar oferecer suporte a ambientes mais antigos e a transpilação não for uma opção para você, use um polyfill, como o recomendado por georg:
fonte
Object.entries = obj => Object.keys(obj).map(k => [k, obj[k]])
Object.entries
pousou no Nó 7.x propriamente dito (sem bandeira) btwPor favor, veja a resposta de nils usando
Object.entries
e / ou a resposta de bergi usando uma função de gerador . EmboraObject.entries
ainda não estivesse nas especificações quando a pergunta foi feita, estava no estágio 4 , portanto, seguro para polyfill e uso em abril de 2016 (apenas). (Mais sobre os estágios aqui .) E as funções do gerador estavam no ES2015. O OP pediu especificamente para evitar intermediários e, embora o gerador não evite completamente isso, ele faz um trabalho melhor do que o abaixo ou (ligeiramente)Object.enties
.FWIW, usando
Object.entries
:[name, value]
matrizes para passar paranew Map
Map
construtor chama uma função na matriz para obter um iterador; a matriz cria e retorna um objeto interator de matriz.Map
construtor usa esse objeto iterador para obter as entradas (os[name, value]
arrays) e construir o mapaUsando o gerador:
Map
construtor chama uma função nesse objeto gerador para obter um iterador dele; o objeto gerador retorna a si mesmoMap
construtor usa o objeto gerador (como um iterador) para obter as entradas (os[name, value]
arrays) e construir o mapaPortanto: Um intermediário a menos (a matriz de
Object.entries
).No entanto, usar
Object.entries
é mais simples e criar essa matriz não é um problema 99,999% do tempo. Então, realmente, qualquer um. Mas ambos são melhores do que os de baixo. :-)Resposta original:
Para inicializar um
Map
, você pode usar qualquer iterador que retorne pares de chave / valor como matrizes, como uma matriz de matrizes:Não há conversão integrada de objeto em mapa, mas é facilmente feita com
Object.keys
:Você pode, é claro, atribuir a si mesmo uma função de trabalhador para cuidar disso:
Então
Ou aqui está uma versão mais l33t (isso ainda é uma coisa?):
(Sim,
Map#set
retorna a referência do mapa. Alguns diriam que isso é um abuso dereduce
.)Ou podemos realmente exagerar na obscuridade:
Não, eu nunca faria isso de verdade. :-)
fonte
var buildMap2 = o => new Map(Object.keys(o).map(k => [k, o[k]]));
.new Map(Object.entries(object))
stackoverflow.com/a/36644558/798133Não, um iterador de matrizes de pares de valores-chave é suficiente. Você pode usar o seguinte para evitar a criação da matriz intermediária:
fonte
if(!obj.hasOwnProperties(key)) continue;
certo após a condição do loop for para garantir que não produza propriedades herdadas do protótipo do objeto (a menos que você confie no objeto, mas deve fazer isso de qualquer maneira ao iterar objetos usandoin
como um bom hábito)..hasOwnProperty
propriedade e deverá usáObject.prototype.hasOwnProperty.call(obj, key)
call
. Todas as convenções que recomendamobj.hasOwnProperties(key)
parecem não ter ideia do que estão fazendo.Object
em aMap
é uma operação cara e o OP solicitou especificamente uma solução sem intermediários. Então, por que essa não é a resposta esperada? Bem, perguntar isso provavelmente é fútil, apenas me irrita.function* entries<T>(obj: T): Generator<readonly [keyof T, T[keyof T]]> {…}
. Tambémyield [key, obj[key]] as const;
ajudaria o TypeScript a perceber que está gerando tuplas, não arrays.A resposta de Nils descreve como converter objetos em mapas, o que achei muito útil. No entanto, o OP também estava se perguntando onde essas informações estão nos documentos MDN. Embora possa não estar lá quando a pergunta foi feita originalmente, agora está na página MDN de Object.entries () sob o título Convertendo um Objeto em um Mapa que afirma:
fonte
fonte
var buildMap2 = o => new Map(Object.keys(o).map(k => [k, o[k]]));
.Como alternativa, você pode usar o método Lodash toPairs :
fonte
ES6
converter objeto em mapa:
converter mapa em objeto:
Observação: a função mapToObj assume que as teclas do mapa são strings (caso contrário, falhará)
fonte
Com a ajuda de um pouco de JQuery,
fonte