web-dev-qa-db-ja.com

セットをJSON文字列化する

どのようになりますか JSON.stringify() a Set

Chromium 43で機能しなかったもの:

var s = new Set(['foo', 'bar']);

JSON.stringify(s); // -> "{}"
JSON.stringify(s.values()); // -> "{}"
JSON.stringify(s.keys()); // -> "{}"

シリアル化されたアレイのそれに似たものが得られると期待しています。

JSON.stringify(["foo", "bar"]); // -> "["foo","bar"]"
66
MitMaro

JSON.stringifyは、セットに保存されたデータがプロパティとして保存されないため、セットで直接機能しません。

ただし、セットを配列に変換できます。その後、適切に文字列化することができます。

次のいずれかがトリックを行います。

JSON.stringify([...s]);
JSON.stringify([...s.keys()]);
JSON.stringify([...s.values()]);
JSON.stringify(Array.from(s));
JSON.stringify(Array.from(s.keys()));
JSON.stringify(Array.from(s.values()));
69
Oriol

これを使って JSON.stringify置換:

toJSONはレガシーアーティファクトであり、より良いアプローチはカスタムreplacerを使用することです。 https://github.com/DavidBruant/Map-Set.prototype.toJSON/issues/16

function Set_toJSON(key, value) {
  if (typeof value === 'object' && value instanceof Set) {
    return [...value];
  }
  return value;
}

次に:

const fooBar = { foo: new Set([1, 2, 3]), bar: new Set([4, 5, 6]) };
JSON.stringify(fooBar, Set_toJSON)

結果:

"{"foo":[1,2,3],"bar":[4,5,6]}"
16
tanguy_k

上記のすべてが機能する間、サブクラスを設定してtoJSONメソッドを追加し、それが正しく文字列化されることを確認することをお勧めします。特に、頻繁にストリング化する場合。 Reduxストアでセットを使用し、これが問題にならないようにする必要がありました。

これは基本的な実装です。命名は、ポイントがあなた自身のスタイルを選ぶことを説明するためだけです。

class JSONSet extends Set {
    toJSON () {
        return [...this]
    }
}

const set = new JSONSet([1, 2, 3])
console.log(JSON.stringify(set))
4
Stephen Bolton