Por alguna razón, no puedo encontrar esta cosa simple en los documentos de MDN (tal vez me lo pierda).
Esperaba que esto funcionara:
const map = new Map({foo: 'bar'});
map.get('foo'); // 'bar'
... pero la primera línea arroja TypeError: (var)[Symbol.iterator] is not a function
¿Cómo hago un mapa a partir de un objeto plano? ¿Realmente tengo que convertirlo primero en una matriz de matrices de pares clave-valor?
javascript
ecmascript-6
callum
fuente
fuente
Object.entries
realmente es el mejor enfoqueObject.keys
, y el enfoque de función del generador de bergi es un poco más directo queObject.keys
oObject.entries
.Respuestas:
Sí, el
Map
constructor toma una matriz de pares clave-valor.Object.entries
es un nuevo método estático de objetos disponible en ES2017 (19.1.2.5) .Actualmente está implementado en Firefox 46+ y Edge 14+ y versiones más recientes de Chrome
Si necesita admitir entornos más antiguos y la transpilación no es una opción para usted, use un polyfill, como el recomendado por georg:
fuente
Object.entries = obj => Object.keys(obj).map(k => [k, obj[k]])
Object.entries
aterrizó en el Nodo 7.x propiamente dicho (sin bandera) por ciertoVea la respuesta de nils usando
Object.entries
y / o la respuesta de bergi usando una función generadora . Aunque aúnObject.entries
no estaba en la especificación cuando se hizo la pregunta, estaba en la Etapa 4 , por lo que es seguro para rellenar y usar incluso en abril de 2016 (solo). (Más sobre las etapas aquí .) Y las funciones del generador estaban en ES2015. El OP pidió específicamente evitar intermediarios, y aunque el generador no lo evita por completo, hace un mejor trabajo que el siguiente o (ligeramente)Object.enties
.FWIW, usando
Object.entries
:[name, value]
matrices para pasar anew Map
Map
constructor llama a una función en la matriz para obtener un iterador; la matriz crea y devuelve un objeto interador de matriz.Map
constructor usa ese objeto iterador para obtener las entradas (las[name, value]
matrices) y construir el mapaUsando el generador:
Map
constructor llama a una función en ese objeto generador para obtener un iterador de él; el objeto generador se devuelve a sí mismoMap
constructor usa el objeto generador (como iterador) para obtener las entradas (las[name, value]
matrices) y construir el mapaEntonces: Un intermediario menos (la matriz de
Object.entries
).Sin embargo, usar
Object.entries
es más simple y crear esa matriz no es un problema el 99,999% de las veces. Entonces realmente, cualquiera. Pero ambos son mejores que los siguientes. :-)Respuesta original:
Para inicializar a
Map
, puede utilizar cualquier iterador que devuelva pares clave / valor como matrices, como una matriz de matrices:No hay conversión incorporada de objeto a mapa, pero se hace fácilmente con
Object.keys
:Por supuesto, puedes darte una función de trabajador para manejar eso:
Luego
O aquí hay una versión más l33t (¿sigue siendo una cosa?):
(Sí,
Map#set
devuelve la referencia del mapa. Algunos dirían que se trata de un abuso dereduce
).O realmente podemos exagerar en la oscuridad:
No, nunca haría eso de verdad. :-)
fuente
var buildMap2 = o => new Map(Object.keys(o).map(k => [k, o[k]]));
.new Map(Object.entries(object))
stackoverflow.com/a/36644558/798133No, un iterador de matrices de pares clave-valor es suficiente. Puede utilizar lo siguiente para evitar crear la matriz intermedia:
fuente
if(!obj.hasOwnProperties(key)) continue;
derecho después de la condición de bucle for para asegurarse de no ceder propiedades heredadas del prototipo del objeto (a menos que confíe en el objeto, pero debería hacerlo de todos modos al iterar objetos usandoin
como un buen hábito)..hasOwnProperty
propiedad, y tendría que usarloObject.prototype.hasOwnProperty.call(obj, key)
call
. Todas las convenciones que recomiendanobj.hasOwnProperties(key)
parecen no tener idea de lo que están haciendo.Object
en unMap
es una operación costosa y el OP pidió específicamente una solución sin intermediarios. Entonces, ¿por qué no es esta la respuesta exceptuada? Bueno, preguntar esto probablemente sea inútil, simplemente me molesta.function* entries<T>(obj: T): Generator<readonly [keyof T, T[keyof T]]> {…}
. Tambiényield [key, obj[key]] as const;
ayudaría a TypeScript a darse cuenta de que está produciendo tuplas, no matrices.La respuesta de Nils describe cómo convertir objetos en mapas, lo que encontré muy útil. Sin embargo, el OP también se preguntaba dónde está esta información en los documentos de MDN. Si bien es posible que no estuviera allí cuando se hizo la pregunta originalmente, ahora está en la página MDN para Object.entries () bajo el encabezado Convertir un objeto en un mapa que dice:
fuente
fuente
var buildMap2 = o => new Map(Object.keys(o).map(k => [k, o[k]]));
.Alternativamente, puede usar el método lodash toPairs :
fuente
ES6
convertir objeto a mapa:
convertir mapa en objeto:
Nota: la función mapToObj asume que las claves del mapa son cadenas (fallarán de lo contrario)
fuente
Con la ayuda de JQuery,
fuente