JSONはセットを文字列化します


98

どのようにでしょうJSON.stringify()セット

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"]"

回答:


104

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()));

2
提案するつもりだったArray.from()。しかし、これは慣用的によく見えます。
TaoPR、2015

3
参照を追加するだけで、MDNにはこれと他の関連するテクニックの例がいくつかあります
Amit

5
リスト内包も同様に仕事ができる:JSON.stringify([_ for (_ of s)])
Whymarrh

1
悲しいことに、spreadとArray.fromがまだ実装されていないため、Chromium 43ではそのままでは機能しません。救助にバベルのように見えます。
MitMaro

2
デフォルト改善するための現在の提案Set.prototype.toJSONgithub.com/DavidBruant/Map-Set.prototype.toJSON
Oncleトム

34

この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]}"

5
ES6には短縮バージョンがありますJSON.stringify(fooBar, (key, value) => value instanceof Set ? [...value] : value)
OzzyCzech

対応する復活者は、読者のための演習として残されていますか?;-)
Robert Siemer

7

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

これは基本的な実装です。ネーミングは、自分のスタイルを選ぶポイントを説明するためのものです。

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

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

4
toJSONレガシー機能と見なされているため、このアプローチはお勧めしません。追加する提案toJSONの両方にsetし、map拒否されました:github.com/DavidBruant/Map-Set.prototype.toJSON/issues/16
MitMaro

オーバーライドするconstructor必要はありません。
ジャスティンジョンソン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.