web-dev-qa-db-ja.com

ES6マップをどのようにJSON.stringifyしますか?

JSオブジェクトの代わりに ES6 Map の使用を開始したいのですが、マップをJSON.stringify()する方法がわからないため、私は抑制されています。キーは文字列であることが保証され、値は常にリストになります。シリアライズするためにラッパーメソッドを書く必要が本当にありますか?

66
rynop

できません。

マップのキーは、オブジェクトを含め、何でもかまいません。ただし、JSON構文では、文字列のみをキーとして使用できます。したがって、一般的なケースでは不可能です。

キーは文字列であることが保証され、値は常にリストになります

この場合、プレーンオブジェクトを使用できます。次の利点があります。

  • JSONに文字列化できます。
  • 古いブラウザで動作します。
  • 速いかもしれません。
45
Oriol

Mapインスタンスにはプロパティがないため、直接文字列化することはできませんが、タプルの配列に変換することはできます。

jsonText = JSON.stringify(Array.from(map.entries()));

逆の場合は、

map = new Map(JSON.parse(jsonText));
19
Bergi

両方 JSON.stringifyおよびJSON.parseは2番目の引数をサポートします。 replacerおよびreviver。以下の置換およびリバイバーを使用すると、深くネストされた値を含むネイティブMapオブジェクトのサポートを追加できます。

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;
}

使用法

const originalValue = new Map([['a', 1]]);
const str = JSON.stringify(originalValue, replacer);
const newValue = JSON.parse(str, reviver);
console.log(originalValue, newValue);

配列、オブジェクト、マップの組み合わせによる深いネスト

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);
9
Pawel

Ecmascriptによって提供されるメソッドはまだありませんが、JSON.stingifyMapをJavaScriptプリミティブにマップする場合。使用するサンプルMapは次のとおりです。

const map = new Map();
map.set('foo', 'bar');
map.set('baz', 'quz');

JavaScriptオブジェクトに移動する

次のヘルパー関数を使用して、JavaScriptオブジェクトリテラルに変換できます。

const mapToObj = m => {
  return Array.from(m).reduce((obj, [key, value]) => {
    obj[key] = value;
    return obj;
  }, {});
};

JSON.stringify(mapToObj(map)); // '{"foo":"bar","baz":"quz"}'

オブジェクトのJavaScript配列に移動する

これのヘルパー関数はさらにコンパクトになります

const mapToAoO = m => {
  return Array.from(m).map( ([k,v]) => {return {[k]:v}} );
};

JSON.stringify(mapToAoO(map)); // '[{"foo":"bar"},{"baz":"quz"}]'

配列の配列に移動

これはさらに簡単です。

JSON.stringify( Array.from(map) ); // '[["foo","bar"],["baz","quz"]]'
6
Evan Carroll

以下のソリューションは、ネストされたマップがある場合でも機能します

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);
}
0
Imamudin Naseem