如何将 JavaScript ES6 Map 对象显示到控制台?
How can I Display a JavaScript ES6 Map Object to Console?
我正在使用 repl.it/languages/javascript。
在打印出来之前是否必须将其转换为对象?
我试过了
const mapObject = new Map();
mapObject.set(1, 'hello');
console.log(JSON.stringify(mapObject));
console.log(mapObject);
结果总是空对象。
当我使用
console.log([...mapObject]);
它打印出一个数组格式。
注意:此答案仅与 OP 正在使用的 repl.it 沙箱环境有关
既然您在评论中说您正在使用 repl.it,那么您可以使用一个技巧来编写自己的 "logging strategy"。
请注意,您不应该在生产中使用此技巧,主要是因为它编辑的是原生原型。在某些 Node 环境中,在您自己的代码中,它可能会有用。
我们的想法是为 Map
创建一个 inspect
方法来迭代 entries
:
Map.prototype.inspect = function() {
return `Map(${mapEntriesToString(this.entries())})`
}
function mapEntriesToString(entries) {
return Array
.from(entries, ([k, v]) => `\n ${k}: ${v}`)
.join("") + "\n";
}
可以看到repl.it支持here
console.log(new Map([["a", 1], ["b", 2]]));
// Logs:
/*
Map(
a: 1
b: 2
)
*/
你可以使用console.log(mapObject.values())
您可以尝试更简单的解决方案。
const mapObject = new Map();
mapObject.set(1, 'hello');
console.log([...mapObject.entries()]);
// [[1, "hello"]]
console.log([...mapObject.keys()]);
// [1]
console.log([...mapObject.values()]);
// ["hello"]
对于深度为 1 的简单地图,只需使用 Object.fromEntries([...map])
将对象条目数组转换回控制台可记录对象:
const simpleObj = {
a: [1, 2, 3],
b: {c: {d: 42}}
};
const map = new Map(Object.entries(simpleObj));
console.log(Object.fromEntries([...map]));
但是,对于复杂的嵌套地图,这会失败。为此,我们可以递归地将任何 Map
转换为对象,然后正常记录它。这是一个 proof-of-concept 的复杂结构,它结合了普通对象、Map
、数组和基元。不要指望它涵盖开箱即用的所有边缘情况,但请随时指出改进之处。
const convertMapToObjDeeply = o => {
const recurseOnEntries = a => Object.fromEntries(
a.map(([k, v]) => [k, convertMapToObjDeeply(v)])
);
if (o instanceof Map) {
return recurseOnEntries([...o]);
}
else if (Array.isArray(o)) {
return o.map(convertMapToObjDeeply);
}
else if (typeof o === "object" && o !== null) {
return recurseOnEntries(Object.entries(o));
}
return o;
};
const mkMap = o => new Map(Object.entries(o));
const map = mkMap({
a: 42,
b: [1, 2, 3, mkMap({d: mkMap({ff: 55})})],
c: mkMap({
e: [4, 5, 6, {f: 5, x: y => y}, mkMap({g: z => 1})]
}),
h: {i: mkMap({j: 46, jj: new Map([[[1, 6], 2]])})},
k: mkMap({l: mkMap({m: [2, 5, x => x, 99]})})
});
console.log(convertMapToObjDeeply(map));
我意识到这很可能是为浏览器控制台设计的,但这也发生在 Node 中。因此,您可以在 Node 中使用它来查看地图(或可能包含地图的对象):
import * as util from "util";
const map: Map<string, string> = new Map();
map.set("test", "test");
const inspected: string = util.inspect(map);
console.log(inspected);
试试这个:
let mapObject = new Map();
mapObject.set("one", "file1");
mapObject.set("two", "file2");
mapObject.set("three", "file3");
console.log([...mapObject.entries()]);
输出将是:
[ [ 'one', 'file1' ], [ 'two', 'file2' ], [ 'three', 'file3' ] ]
此解决方案的问题在于,如果我们添加之前的字符串,输出会发生变化:
console.log("This is a map: " + [...mapObject.entries()]);
输出将是:
This is a map: one,file1,two,file2,three,file3
可以找到解决方案
我正在使用 repl.it/languages/javascript。
在打印出来之前是否必须将其转换为对象?
我试过了
const mapObject = new Map();
mapObject.set(1, 'hello');
console.log(JSON.stringify(mapObject));
console.log(mapObject);
结果总是空对象。
当我使用
console.log([...mapObject]);
它打印出一个数组格式。
注意:此答案仅与 OP 正在使用的 repl.it 沙箱环境有关
既然您在评论中说您正在使用 repl.it,那么您可以使用一个技巧来编写自己的 "logging strategy"。
请注意,您不应该在生产中使用此技巧,主要是因为它编辑的是原生原型。在某些 Node 环境中,在您自己的代码中,它可能会有用。
我们的想法是为 Map
创建一个 inspect
方法来迭代 entries
:
Map.prototype.inspect = function() {
return `Map(${mapEntriesToString(this.entries())})`
}
function mapEntriesToString(entries) {
return Array
.from(entries, ([k, v]) => `\n ${k}: ${v}`)
.join("") + "\n";
}
可以看到repl.it支持here
console.log(new Map([["a", 1], ["b", 2]]));
// Logs:
/*
Map(
a: 1
b: 2
)
*/
你可以使用console.log(mapObject.values())
您可以尝试更简单的解决方案。
const mapObject = new Map();
mapObject.set(1, 'hello');
console.log([...mapObject.entries()]);
// [[1, "hello"]]
console.log([...mapObject.keys()]);
// [1]
console.log([...mapObject.values()]);
// ["hello"]
对于深度为 1 的简单地图,只需使用 Object.fromEntries([...map])
将对象条目数组转换回控制台可记录对象:
const simpleObj = {
a: [1, 2, 3],
b: {c: {d: 42}}
};
const map = new Map(Object.entries(simpleObj));
console.log(Object.fromEntries([...map]));
但是,对于复杂的嵌套地图,这会失败。为此,我们可以递归地将任何 Map
转换为对象,然后正常记录它。这是一个 proof-of-concept 的复杂结构,它结合了普通对象、Map
、数组和基元。不要指望它涵盖开箱即用的所有边缘情况,但请随时指出改进之处。
const convertMapToObjDeeply = o => {
const recurseOnEntries = a => Object.fromEntries(
a.map(([k, v]) => [k, convertMapToObjDeeply(v)])
);
if (o instanceof Map) {
return recurseOnEntries([...o]);
}
else if (Array.isArray(o)) {
return o.map(convertMapToObjDeeply);
}
else if (typeof o === "object" && o !== null) {
return recurseOnEntries(Object.entries(o));
}
return o;
};
const mkMap = o => new Map(Object.entries(o));
const map = mkMap({
a: 42,
b: [1, 2, 3, mkMap({d: mkMap({ff: 55})})],
c: mkMap({
e: [4, 5, 6, {f: 5, x: y => y}, mkMap({g: z => 1})]
}),
h: {i: mkMap({j: 46, jj: new Map([[[1, 6], 2]])})},
k: mkMap({l: mkMap({m: [2, 5, x => x, 99]})})
});
console.log(convertMapToObjDeeply(map));
我意识到这很可能是为浏览器控制台设计的,但这也发生在 Node 中。因此,您可以在 Node 中使用它来查看地图(或可能包含地图的对象):
import * as util from "util";
const map: Map<string, string> = new Map();
map.set("test", "test");
const inspected: string = util.inspect(map);
console.log(inspected);
试试这个:
let mapObject = new Map();
mapObject.set("one", "file1");
mapObject.set("two", "file2");
mapObject.set("three", "file3");
console.log([...mapObject.entries()]);
输出将是:
[ [ 'one', 'file1' ], [ 'two', 'file2' ], [ 'three', 'file3' ] ]
此解决方案的问题在于,如果我们添加之前的字符串,输出会发生变化:
console.log("This is a map: " + [...mapObject.entries()]);
输出将是:
This is a map: one,file1,two,file2,three,file3
可以找到解决方案