Converting ES6 Maps to and from JSON
When you have key-value data whose keys you don’t know in advance, it’s generally better to store it in an ES6 Map than in an object. But how do you convert Maps to and from JSON? This blog post tells you.
Background knowledge:
- More information on ES6 Maps: chapter “Maps and Sets” in “Exploring ES6”.
- More information on JSON: chapter “JSON” in “Speaking JavaScript”.
Arbitrary Maps as JSON via Arrays of pairs
If a Map contains arbitrary (JSON-compatible) data, we can convert it to JSON by encoding it as an Array of key-value pairs (2-element Arrays).
Converting a Map to and from an Array of pairs
The spread operator lets you convert a Map to an Array of pairs:
> let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
> [...myMap]
[ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]
The Map
constructor lets you convert an Array of pairs to a Map:
> new Map([[true, 7], [{foo: 3}, ['abc']]])
Map {true => 7, Object {foo: 3} => ['abc']}
The conversion to and from JSON
Let’s use this knowledge to convert any Map with JSON-compatible data to JSON and back:
function mapToJson(map) {
return JSON.stringify([...map]);
}
function jsonToMap(jsonStr) {
return new Map(JSON.parse(jsonStr));
}
The following interaction demonstrates how these functions are used:
> let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
> mapToJson(myMap)
'[[true,7],[{"foo":3},["abc"]]]'
> jsonToMap('[[true,7],[{"foo":3},["abc"]]]')
Map {true => 7, Object {foo: 3} => ['abc']}
String Maps as JSON via objects
Whenever a Map only has strings as keys, you can convert it to JSON by encoding it as an object.
Converting a string Map to and from an object
The following two function convert string Maps to and from objects:
function strMapToObj(strMap) {
let obj = Object.create(null);
for (let [k,v] of strMap) {
// We don’t escape the key '__proto__'
// which can cause problems on older engines
obj[k] = v;
}
return obj;
}
function objToStrMap(obj) {
let strMap = new Map();
for (let k of Object.keys(obj)) {
strMap.set(k, obj[k]);
}
return strMap;
}
Let’s use these two functions:
> let myMap = new Map().set('yes', true).set('no', false);
> strMapToObj(myMap)
{ yes: true, no: false }
> objToStrMap({yes: true, no: false})
[ [ 'yes', true ], [ 'no', false ] ]
The conversion to and from JSON
With these helper functions, the conversion to JSON works as follows:
function strMapToJson(strMap) {
return JSON.stringify(strMapToObj(strMap));
}
function jsonToStrMap(jsonStr) {
return objToStrMap(JSON.parse(jsonStr));
}
This is an example of using these functions:
> let myMap = new Map().set('yes', true).set('no', false);
> strMapToJson(myMap)
'{"yes":true,"no":false}'
> jsonToStrMap('{"yes":true,"no":false}');
Map {'yes' => true, 'no' => false}
Comments
Post a Comment