javascript - crear - ¿Cómo JSON.stringify un mapa ES6?
string to json javascript (5)
Aunque todavía no hay un método proporcionado por ecmascript, esto todavía se puede hacer usando
JSON.stingify
si
JSON.stingify
el
Map
a una primitiva de JavaScript.
Aquí está el
Map
muestra que usaremos.
const map = new Map();
map.set(''foo'', ''bar'');
map.set(''baz'', ''quz'');
Ir a un objeto JavaScript
Puede convertir a JavaScript Object literal 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 JavaScript de objetos
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 la matriz de matrices
Esto es aún más fácil, solo puedes usar
JSON.stringify( Array.from(map) ); // ''[["foo","bar"],["baz","quz"]]''
Me gustaría comenzar a usar ES6 Map en lugar de objetos JS, pero estoy retenido porque no puedo entender cómo JSON.stringify () un Map. Se garantiza que mis claves serán cadenas y mis valores siempre serán listas. ¿Realmente tengo que escribir un método de contenedor para serializar?
La siguiente solución funciona incluso si tiene mapas anidados
function stringifyMap(myMap) {
function selfIterator(map) {
return Array.from(map).reduce((acc, [key, value]) => {
if (value instanceof Map) {
acc[key] = selfIterator(value);
} else {
acc[key] = value;
}
return acc;
}, {})
}
const res = selfIterator(myMap)
return JSON.stringify(res);
}
No puede encadenar directamente la instancia de
Map
ya que no tiene ninguna propiedad, pero puede convertirla en una matriz de tuplas:
jsonText = JSON.stringify(Array.from(map.entries()));
Para el reverso, 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 solo permite cadenas como claves. Entonces es imposible en un caso general.
Mis claves están garantizadas como cadenas y mis valores siempre serán listas
En este caso, puede usar un objeto plano. Tendrá estas ventajas:
- Podrá ser stringified a JSON.
- Funcionará en navegadores antiguos.
- Puede ser más rápido
Tanto
JSON.stringify
como
JSON.parse
admiten un segundo argumento.
replacer
y
reviver
respectivamente.
Con el sustituto y el revividor a continuación, es posible agregar soporte para el objeto Map nativo, incluidos los valores profundamente anidados
function replacer(key, value) {
const originalObject = this[key];
if(originalObject instanceof Map) {
return {
dataType: ''Map'',
value: Array.from(originalObject.entries()), // or with spread: value: [...originalObject]
};
} 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);