最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Serialize Map object with jQueryJS - Stack Overflow

programmeradmin5浏览0评论

[This is first question on SO, so apologize me for any mistake]

I'm trying to save a Map, like the one below, in a cookie.

var myMap = new Map();
myMap.set("k1", {
    a1: "...",
    a2: "...",
    a3: "..."
});

For this, I have to format as JSON. I tried many methods, like:

$.toJSON(myMap)
$.param(myMap)
JSON.stringify(myMap)

But none of them seems to work...

So, I did this:

var serial = [];
myMap.forEach(function(value){
    serial.push(value);
});
var result = $.toJSON(serial)

(Having to reconstruct the key on decoding the JSON...)

There is a better way to serialize a Map object?

[This is first question on SO, so apologize me for any mistake]

I'm trying to save a Map, like the one below, in a cookie.

var myMap = new Map();
myMap.set("k1", {
    a1: "...",
    a2: "...",
    a3: "..."
});

For this, I have to format as JSON. I tried many methods, like:

$.toJSON(myMap)
$.param(myMap)
JSON.stringify(myMap)

But none of them seems to work...

So, I did this:

var serial = [];
myMap.forEach(function(value){
    serial.push(value);
});
var result = $.toJSON(serial)

(Having to reconstruct the key on decoding the JSON...)

There is a better way to serialize a Map object?

Share Improve this question edited Oct 15, 2017 at 4:47 Marcos Paulo asked Oct 14, 2017 at 5:22 Marcos PauloMarcos Paulo 3373 silver badges10 bronze badges 0
Add a ment  | 

4 Answers 4

Reset to default 9

Not exactly a typical "stringify", but you can use the spread operator bined with JSON.stringify(), that will give you an array...

var myMap = new Map();
myMap.set("k1", { a1: "...", a2: "...", a3: "..." });
myMap.set("k2", { b1: "...", b2: "...", b3: "..." });

var myJSON = JSON.stringify([...myMap]);
alert(myJSON);

This will give you...

[["k1",{"a1":"...","a2":"...","a3":"..."}],["k2",{"b1":"...","b2":"...","b3":"..."}]]

And to convert it to Map again...

var recoveredMap = new Map(JSON.parse(myJSON));

While spread operator is good if you want to stringify immediate maps, you'll face problems if they are nested within any data structures.

Both JSON.stringify and JSON.parse support callback functions:

JSON.stringify(value[, replacer[, space]])
JSON.parse(text[, reviver])

So you can write functions such as:

function replacer (key, value){
    if (value.__proto__ == Map.prototype) {
        return {
            _type: "map",
            map: [...value],
        }
    } else return value;
}

function reviver (key, value){
    if (value._type == "map") return new Map(value.map);
    else return value;
}

Now you can easily stringify/parse maps no matter how deep they are nested:

let obj = {
    map: new Map([
        [1, new Map([
            [1,2],
            [3,4],
        ])],
        [2,3],
    ]),
};
console.log(obj);
let str = JSON.stringify(obj, replacer);
console.log(str);
console.log(JSON.parse(str));
console.log(JSON.parse(str, reviver));

What about using Array.from to convert your Map into an array

// initialize the map
var myMap = new Map();
myMap.set("k1", {
  a1: "...",
  a2: "...",
  a3: "..."
});
myMap.set("k2", {
  a1: "...",
  a2: "...",
  a3: "..."
});


// serialize the map by converting it to an array
var mapAsArray = Array.from(myMap);
console.log('Map as array ',mapAsArray);

var serializedMap = JSON.stringify(mapAsArray);
console.log(serializedMap)

// deserialize into a new map
var map = new Map(JSON.parse(serializedMap))
console.log(map.size)

There's a new JS feature - Object.fromEntries. It can parse a map into an object

const obj = {a: 1, b: 2}
const map = new Map(Object.entries(obj))
const objectCopy = Object.fromEntries(map)

Compatibility is ok (Chrome, FF, Safari) and a polyfill exists. We can also expect patibility to spread to all browsers since fromEntries is a "stage 4" proposal (approved).
See Compatibility here

发布评论

评论列表(0)

  1. 暂无评论