ryn*_*nop 71 javascript json dictionary ecmascript-6
我想开始使用ES6 Map而不是JS对象,但我被阻止了,因为我无法弄清楚如何使用JSON.stringify()一个Map.我的密钥保证是字符串,我的值将始终是列表.我是否真的必须编写一个包装器方法来序列化?
Ori*_*iol 46
你不能.
地图的键可以是任何东西,包括对象.但JSON语法只允许字符串作为键.所以在一般情况下这是不可能的.
我的密钥保证是字符串,我的值将始终是列表
在这种情况下,您可以使用普通对象.它将具有以下优势:
Ber*_*rgi 33
您不能直接对Map
实例进行字符串化,因为它没有任何属性,但您可以将其转换为元组数组:
jsonText = JSON.stringify(Array.from(map.entries()));
Run Code Online (Sandbox Code Playgroud)
反之,请使用
map = new Map(JSON.parse(jsonText));
Run Code Online (Sandbox Code Playgroud)
met*_*bic 25
使用spread sytax Map 可以在一行中序列化:
JSON.stringify([...new Map()]);
Run Code Online (Sandbox Code Playgroud)
并将其反序列化:
let map = new Map(JSON.parse(map));
Run Code Online (Sandbox Code Playgroud)
Paw*_*wel 18
双方JSON.stringify
并JSON.parse
支持第二个参数。replacer
和reviver
分别。通过以下的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;
}
}
Run Code Online (Sandbox Code Playgroud)
function reviver(key, value) {
if(typeof value === 'object' && value !== null) {
if (value.dataType === 'Map') {
return new Map(value.value);
}
}
return value;
}
Run Code Online (Sandbox Code Playgroud)
用法:
const originalValue = new Map([['a', 1]]);
const str = JSON.stringify(originalValue, replacer);
const newValue = JSON.parse(str, reviver);
console.log(originalValue, newValue);
Run Code Online (Sandbox Code Playgroud)
结合使用数组,对象和贴图的深度嵌套
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);
Run Code Online (Sandbox Code Playgroud)
小智 12
鉴于您的示例是一个简单的用例,其中键将是简单类型,我认为这是 JSON 字符串化 Map 的最简单方法。
JSON.stringify(Object.fromEntries(map));
Run Code Online (Sandbox Code Playgroud)
我认为 Map 底层数据结构的方式是作为键值对的数组(作为数组本身)。所以,像这样:
const myMap = new Map([
["key1", "value1"],
["key2", "value2"],
["key3", "value3"]
]);
Run Code Online (Sandbox Code Playgroud)
因为底层数据结构是我们在 Object.entries 中找到的,所以我们可以Object.fromEntries()
像在 Array 上一样使用 Map 上的原生 JavaScript 方法:
Object.fromEntries(myMap);
/*
{
key1: "value1",
key2: "value2",
key3: "value3"
}
*/
Run Code Online (Sandbox Code Playgroud)
然后你剩下的就是在结果上使用 JSON.stringify() 。
Ste*_*tch 12
只需复制并使用它即可。或者使用npm 包。
const serialize = (value) => JSON.stringify(value, stringifyReplacer);
const deserialize = (text) => JSON.parse(text, parseReviver);
// License: CC0
function stringifyReplacer(key, value) {
if (typeof value === "object" && value !== null) {
if (value instanceof Map) {
return {
_meta: { type: "map" },
value: Array.from(value.entries()),
};
} else if (value instanceof Set) { // bonus feature!
return {
_meta: { type: "set" },
value: Array.from(value.values()),
};
} else if ("_meta" in value) {
// Escape "_meta" properties
return {
...value,
_meta: {
type: "escaped-meta",
value: value["_meta"],
},
};
}
}
return value;
}
function parseReviver(key, value) {
if (typeof value === "object" && value !== null) {
if ("_meta" in value) {
if (value._meta.type === "map") {
return new Map(value.value);
} else if (value._meta.type === "set") {
return new Set(value.value);
} else if (value._meta.type === "escaped-meta") {
// Un-escape the "_meta" property
return {
...value,
_meta: value._meta.value,
};
} else {
console.warn("Unexpected meta", value._meta);
}
}
}
return value;
}
Run Code Online (Sandbox Code Playgroud)
应该可以输入任何类型的数据,获取有效的 JSON,并从那里正确地重建输入。
这意味着处理
new Map([ [{cat:1}, "value"] ])
。这意味着任何使用的答案都Object.fromEntries
可能是错误的。new Map([ ["key", new Map([ ["nested key", "nested value"] ])] ])
。很多答案只回答问题而不处理除此之外的任何事情,从而回避了这一点。{"key": new Map([ ["nested key", "nested value"] ]) }
。除了这些困难之外,序列化格式必须明确。否则,人们无法总是重建输入。最上面的答案有一个失败的测试用例,请参见下文。
因此,我写了这个改进版本。它使用,_meta
来代替dataType
, 来减少冲突,并且如果确实发生冲突,它实际上会明确地处理它。希望代码也足够简单,可以轻松扩展以处理其他容器。
然而,我的回答并没有尝试处理极其受诅咒的情况,例如具有对象属性的地图。
我的答案的测试用例,演示了一些边缘情况
const originalValue = [
new Map([['a', {
b: {
_meta: { __meta: "cat" },
c: new Map([['d', 'text']])
}
}]]),
{ _meta: { type: "map" }}
];
console.log(originalValue);
let text = JSON.stringify(originalValue, stringifyReplacer);
console.log(text);
console.log(JSON.parse(text, parseReviver));
Run Code Online (Sandbox Code Playgroud)
接受的答案真的很可爱。dataType
但是,当将具有属性的对象传递给它时,它不会往返。这可能会使其在某些情况下使用变得危险,例如
JSON.stringify(data, acceptedAnswerReplacer)
并通过网络发送。这个答案使用稍微复杂的方案来解决此类问题。
// Test case for the accepted answer
const originalValue = { dataType: "Map" };
const str = JSON.stringify(originalValue, replacer);
const newValue = JSON.parse(str, reviver);
console.log(originalValue, str, newValue);
// > Object { dataType: "Map" } , Map(0)
// Notice how the input was changed into something different
Run Code Online (Sandbox Code Playgroud)
Cod*_*ody 11
// somewhere...
class Klass extends Map {
toJSON() {
var object = { };
for (let [key, value] of this) object[key] = value;
return object;
}
}
// somewhere else...
import { Klass as Map } from '@core/utilities/ds/map'; // <--wherever "somewhere" is
var map = new Map();
map.set('a', 1);
map.set('b', { datum: true });
map.set('c', [ 1,2,3 ]);
map.set( 'd', new Map([ ['e', true] ]) );
var json = JSON.stringify(map, null, '\t');
console.log('>', json);
Run Code Online (Sandbox Code Playgroud)
> {
"a": 1,
"b": {
"datum": true
},
"c": [
1,
2,
3
],
"d": {
"e": true
}
}
Run Code Online (Sandbox Code Playgroud)
希望这比上面的答案更不令人讨厌。
am0*_*0wa 10
字符串化一个Map
实例(对象作为键是可以的):
JSON.stringify([...map])
Run Code Online (Sandbox Code Playgroud)
或者
JSON.stringify(Array.from(map))
Run Code Online (Sandbox Code Playgroud)
或者
JSON.stringify(Array.from(map.entries()))
Run Code Online (Sandbox Code Playgroud)
输出格式:
// [["key1","value1"],["key2","value2"]]
Run Code Online (Sandbox Code Playgroud)
尽管ecmascript还没有提供任何方法,但是JSON.stingify
如果将其映射Map
到JavaScript原语,仍然可以使用此方法。这是Map
我们将使用的示例。
const map = new Map();
map.set('foo', 'bar');
map.set('baz', 'quz');
Run Code Online (Sandbox Code Playgroud)
您可以使用以下帮助函数将其转换为JavaScript Object文字。
const mapToObj = m => {
return Array.from(m).reduce((obj, [key, value]) => {
obj[key] = value;
return obj;
}, {});
};
JSON.stringify(mapToObj(map)); // '{"foo":"bar","baz":"quz"}'
Run Code Online (Sandbox Code Playgroud)
这个的辅助功能会更加紧凑
const mapToAoO = m => {
return Array.from(m).map( ([k,v]) => {return {[k]:v}} );
};
JSON.stringify(mapToAoO(map)); // '[{"foo":"bar"},{"baz":"quz"}]'
Run Code Online (Sandbox Code Playgroud)
这甚至更容易,您可以使用
JSON.stringify( Array.from(map) ); // '[["foo","bar"],["baz","quz"]]'
Run Code Online (Sandbox Code Playgroud)
非常简单的方法。
const map = new Map();
map.set('Key1', "Value1");
map.set('Key2', "Value2");
console.log(Object.fromEntries(map));
Run Code Online (Sandbox Code Playgroud)
` 输出:-
{"Key1": "Value1","Key2": "Value2"}
归档时间: |
|
查看次数: |
30803 次 |
最近记录: |