LoginSignup
5
3

More than 1 year has passed since last update.

複雑にネストされたMapオブジェクトをJSONに変換

Posted at

Map、便利だよね

キーと値のセットを持てるMapオブジェクト。
配列や既存のオブジェクトでは再現できないときに超便利。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Map

JSONに変換してPOSTしたい

しかし、これをバックエンドにPOSTするためにJSONに変換するときにひと悶着起きる。

var map = new Map();
map.set('hoge','value1');
map.set('fuga','value2');
JSON.stringify(map);  
// '{}' からっぽ!

これは以下のようにすることで解決できる

var map = new Map();
map.set('hoge','value1');
map.set('fuga','value2');
JSON.stringify(Object.fromEntries(map));
// '{"hoge":"value1","fuga":"value2"}'

なお、JSON.stringify([...map]); でもJSON出力は可能だが、{'hoge', 'value1'}という形式になってしまうので変換後に扱いにくい。

階層化したMapオブジェクトで躓く

しかしここで、Mapの値にMapがある場合オブジェクト配列内に存在するMapという状況が発生するとややこしくなる。

var map1 = new Map();
var map2 = new Map();
map1.set('hoge','value1');
map1.set('fuga','value2');
map2.set('hogehoge','value3');
map2.set('fugafuga','value4');
map2.set('piyo', map1);
JSON.stringify(Object.fromEntries(map2));
// '{"hoge":"value1","fuga":"value2","piyo":{}}'  piyoがからっぽ!

var obj = {
    name: 'hoge',
    maps: map2
};
// JSON.stringify(Object.fromEntries(obj));  // MAPじゃないのでエラー
JSON.stringify(obj);
// '{"name":"hoge","maps":{}}'  当然Mapはからっぽ!

JSON.stringifyのreplacerを使う

replacerを使って型チェックを行い、MapオブジェクトならObject.fromEntriesをかけてやる。

function replacer(key, value) {
    if (value instanceof Map) {
        return Object.fromEntries(value);
    } else {
        return value;
    }
}

JSON.stringify(map2, replacer);
/*
{
  "hogehoge": "value3",
  "fugafuga": "value4",
  "piyo": {
    "hoge": "value1",
    "fuga": "value2"
  }
}
*/

JSON.stringify(obj, replacer);
/*
{
  "name": "hoge",
  "maps": {
    "hogehoge": "value3",
    "fugafuga": "value4",
    "piyo": {
      "hoge": "value1",
      "fuga": "value2"
    }
  }
}
*/

階層が3つ、4つとなっても問題なく変換できるので、これをバックエンドにPOSTしてやれば良い。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3