¿Cómo se crea JSON.stringify en un mapa ES6?
Me gustaría comenzar a usar ES6 Map en lugar de objetos JS, pero me estoy frenando porque no sé cómo crear JSON.stringify()
un archivo Map
. Se garantiza que mis claves serán cadenas y mis valores siempre aparecerán en la lista. ¿Realmente tengo que escribir un método contenedor para serializar?
Ambos JSON.stringify
y JSON.parse
apoyan un segundo argumento. replacer
y reviver
respectivamente. Con el sustituto y el reviver a continuación, es posible agregar soporte para el objeto Map nativo, incluidos valores profundamente anidados.
function replacer(key, value) {
if(value instanceof Map) {
return {
dataType: 'Map',
value: Array.from(value.entries()), // or with spread: value: [...value]
};
} else {
return value;
}
}
function reviver(key, value) {
if(typeof value === 'object' && value !== null) {
if (value.dataType === 'Map') {
return new Map(value.value);
}
}
return value;
}
Uso :
const originalValue = new Map([['a', 1]]);
const str = JSON.stringify(originalValue, replacer);
const newValue = JSON.parse(str, reviver);
console.log(originalValue, newValue);
Anidamiento profundo con combinación de matrices, objetos y mapas
const originalValue = [
new Map([['a', {
b: {
c: new Map([['d', 'text']])
}
}]])
];
const str = JSON.stringify(originalValue, replacer);
const newValue = JSON.parse(str, reviver);
console.log(originalValue, newValue);
No puedes encadenar directamente la Map
instancia ya que no tiene ninguna propiedad, pero puedes convertirla en una matriz de tuplas:
jsonText = JSON.stringify(Array.from(map.entries()));
Para lo contrario, use
map = new Map(JSON.parse(jsonText));
No puedes.
Las claves de un mapa pueden ser cualquier cosa, incluidos los objetos. Pero la sintaxis JSON sólo permite cadenas como claves. Entonces es imposible en un caso general.
Se garantiza que mis claves serán cadenas y mis valores siempre serán listas
En este caso, puedes utilizar un objeto simple. Tendrá estas ventajas:
- Podrá ser encadenado a JSON.
- Funcionará en navegadores más antiguos.
- Puede que sea más rápido.
Si bien ecmascript aún no proporciona ningún método, esto aún se puede hacer JSON.stringify
si asigna el Map
a una primitiva de JavaScript. Aquí está la muestra Map
que usaremos.
const map = new Map();
map.set('foo', 'bar');
map.set('baz', 'quz');
Ir a un objeto JavaScript
Puede convertir a un objeto literal de JavaScript con la siguiente función auxiliar.
const mapToObj = m => {
return Array.from(m).reduce((obj, [key, value]) => {
obj[key] = value;
return obj;
}, {});
};
JSON.stringify(mapToObj(map)); // '{"foo":"bar","baz":"quz"}'
Ir a una matriz de objetos de JavaScript
La función auxiliar para este sería aún más compacta.
const mapToAoO = m => {
return Array.from(m).map( ([k,v]) => {return {[k]:v}} );
};
JSON.stringify(mapToAoO(map)); // '[{"foo":"bar"},{"baz":"quz"}]'
Ir a una matriz de matrices
Esto es aún más fácil, puedes usar
JSON.stringify( Array.from(map) ); // '[["foo","bar"],["baz","quz"]]'