¿Cómo se crea JSON.stringify en un mapa ES6?

Resuelto rynop asked hace 9 años • 17 respuestas

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?

rynop avatar Mar 17 '15 02:03 rynop
Aceptado

Ambos JSON.stringifyy JSON.parseapoyan un segundo argumento. replacery reviverrespectivamente. 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);
Pawel avatar May 15 '2019 13:05 Pawel

No puedes encadenar directamente la Mapinstancia 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));
Bergi avatar Nov 24 '2018 19:11 Bergi

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.
Oriol avatar Mar 16 '2015 19:03 Oriol

Si bien ecmascript aún no proporciona ningún método, esto aún se puede hacer JSON.stringifysi asigna el Mapa una primitiva de JavaScript. Aquí está la muestra Mapque 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"]]'
Evan Carroll avatar Jan 11 '2019 05:01 Evan Carroll