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

Answers:


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

3
仅添加一些参考MDN就提供了一些此技术和其他相关技术的示例
Amit

5
列表理解也可以起作用:JSON.stringify([_ for (_ of s)])
Whymarrh 2015年

1
所有出色的实现方式,可悲的是它们无法在Chromium 43中立即使用,因为尚未实现spread和Array.from。看起来像通天塔来营救。
MitMaro

2
当前建议,以改善默认值Set.prototype.toJSONgithub.com/DavidBruant/Map-Set.prototype.toJSON
Oncle Tom

34

使用此JSON.stringify替换器:

(因为这toJSON是旧版工件,更好的方法是使用customreplacer,请参见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)
简化

留给读者相应的齐整练习吗?;-)
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被认为是旧功能。提议增加toJSONsetmap被拒绝:github.com/DavidBruant/Map-Set.prototype.toJSON/issues/16
MitMaro

constructor不必重写。
贾斯汀·约翰逊
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.