在 Javascript 中将 Map 转换为 JSON 对象

Posted

技术标签:

【中文标题】在 Javascript 中将 Map 转换为 JSON 对象【英文标题】:Convert Map to JSON object in Javascript 【发布时间】:2016-09-23 02:20:13 【问题描述】:

所以我得到了以下 javascript,其中包含一个键/值对,用于将嵌套路径映射到目录。

function createPaths(aliases, propName, path) 
    aliases.set(propName, path);


map = new Map();

createPaths(map, 'paths.aliases.server.entry', 'src/test');
createPaths(map, 'paths.aliases.dist.entry', 'dist/test');

现在我要做的是从地图中的键创建一个 JSON 对象。

必须的,

paths: 
  aliases: 
    server: 
      entry: 'src/test'
    ,
    dist: 
      entry: 'dist/test'
    
  

不确定是否有现成的方法来执行此操作。任何帮助表示赞赏。

【问题讨论】:

我会用点从那个字符串中减去键名,然后根据我收集的内容构建一个对象。 JSON 是一种表示法。只有一个JSON object,但这不是你想要的。您可能想要Object 就像@RobG 所说的那样。所需的输出不是 JSON,而是 JavaScript 对象。要将该对象转换为 JSON,请使用 JSON.stringify(paths) 谢谢..这正是我的意思 @nixgadgets 哦,好 =) 【参考方案1】:

在MDN 中给出,fromEntries() 自 Node v12 起可用:

const map1 = new Map([
  ['foo', 'bar'],
  ['baz', 42]
]);

const obj = Object.fromEntries(map1);
//  foo: 'bar', baz: 42 

用于将对象转换回地图:

const map2 = new Map(Object.entries(obj));
// Map(2)  'foo' => 'bar', 'baz' => 42 

【讨论】:

【参考方案2】:

我希望这个函数足够不言自明。这是我以前做的工作。

/*
 * Turn the map<String, Object> to an Object so it can be converted to JSON
 */
function mapToObj(inputMap) 
    let obj = ;

    inputMap.forEach(function(value, key)
        obj[key] = value
    );

    return obj;



JSON.stringify(returnedObject)

【讨论】:

ES6 - 实现:mapToObj(inputMap) const obj = ; inputMap.forEach((value, key) => obj[key] = value; );返回对象; 【参考方案3】:

您可以遍历地图和键并分配值

function createPaths(aliases, propName, path) 
    aliases.set(propName, path);


var map = new Map(),
    object = ;

createPaths(map, 'paths.aliases.server.entry', 'src/test');
createPaths(map, 'paths.aliases.dist.entry', 'dist/test');

map.forEach((value, key) => 
    var keys = key.split('.'),
        last = keys.pop();
    keys.reduce((r, a) => r[a] = r[a] || , object)[last] = value;
);

console.log(object);

【讨论】:

别忘了加JSON.stringify(object)! (OP 想要一个 JSON 对象...) 没有 JSON 对象,只是一个尊重 javascript-object-notation 的字符串。 stringify - 我认为 - 不是 op 的问题。【参考方案4】:

只使用 ES6 方式

    Object.fromEntries

const log = console.log;

const map = new Map();
// undefined
map.set(`a`, 1);
// Map(1) "a" => 1
map.set(`b`, 2);
// Map(1) "a" => 1, "b" => 2
map.set(`c`, 3);
// Map(2) "a" => 1, "b" => 2, "c" => 3

// Object.fromEntries ✅
const obj = Object.fromEntries(map);

log(`\nobj`, obj);
// obj  a: 1, b: 2, c: 3 
    ...spread & destructuring assignment

const log = console.log;

const map = new Map();
// undefined
map.set(`a`, 1);
// Map(1) "a" => 1
map.set(`b`, 2);
// Map(1) "a" => 1, "b" => 2
map.set(`c`, 3);
// Map(2) "a" => 1, "b" => 2, "c" => 3

const autoConvertMapToObject = (map) => 
  const obj = ;
  for (const item of [...map]) 
    const [
      key,
      value
    ] = item;
    obj[key] = value;
  
  return obj;


const obj = autoConvertMapToObject(map)

log(`\nobj`, obj);
// obj  a: 1, b: 2, c: 3 

参考

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

https://2ality.com/2015/08/es6-map-json.html

【讨论】:

【参考方案5】:

另一种方法。我很好奇哪个性能更好,但 jsPerf 下降了:(。

var obj = ;

function createPaths(map, path, value)

	if(typeof path === "string") path = path.split(".");
	
	if(path.length == 1)
	
		map[path[0]] = value;
		return;
	
	else
	
		if(!(path[0] in map)) map[path[0]] = ;
		return createPaths(map[path[0]], path.slice(1), value);
	


createPaths(obj, 'paths.aliases.server.entry', 'src/test');
createPaths(obj, 'paths.aliases.dist.entry', 'dist/test');

console.log(obj);

没有递归:

var obj = ;

function createPaths(map, path, value)

    var map = map;
    var path = path.split(".");
    for(var i = 0, numPath = path.length - 1; i < numPath; ++i)
    
        if(!(path[i] in map)) map[path[i]] = ;
        map = map[path[i]];
    
    map[path[i]] = value;


createPaths(obj, 'paths.aliases.server.entry', 'src/test');
createPaths(obj, 'paths.aliases.dist.entry', 'dist/test');
createPaths(obj, 'paths.aliases.dist.dingo', 'dist/test');
createPaths(obj, 'paths.bingo.dist.entry', 'dist/test');

console.log(obj);

var obj = ;

function createPaths(map, path, value)

    var map = map;
    var path = path.split(".");
    
    while(path.length > 1)
    
        map = map[path[0]] = map[path.shift()] || ;
    
    
    map[path.shift()] = value;
  


createPaths(obj, 'paths.aliases.server.entry', 'src/test');
createPaths(obj, 'paths.aliases.dist.entry', 'dist/test');
createPaths(obj, 'paths.aliases.dist.dingo', 'dist/test');
createPaths(obj, 'paths.bingo.dist.entry', 'dist/test');

console.log(obj);

【讨论】:

jsPerf 已关闭数周。 在我使用 console.time 的控制台中,您的代码平均花费了 0.023 毫秒,而接受的答案平均花费了 0.137 毫秒. @evolutionxbox——如果递归被顺序代码替换(可能需要多几行代码),它可能会再次运行得更快。更少的代码并不一定意味着更快。 :-) @RobG 非常正确。这些是非常粗略的性能测试。每个都进行了大约 20 次“运行”。 @RobG:我知道,但是递归太酷了。 :P 我添加了一个没有递归的例子。

以上是关于在 Javascript 中将 Map 转换为 JSON 对象的主要内容,如果未能解决你的问题,请参考以下文章

在 Flutter 中将 Firestore DocumentSnapshot 转换为 Map

在 Scala 中将 Struct 数据类型转换为 Map 数据类型

如何在 presto 中将 varchar 转换为 MAP(VARCHAR,VARCHAR)

在java 8中将地图映射转换为单个值列表[关闭]

如何在android中将HashMap转换为json数组?

在 Dart 中将 Map 的所有键和值转换为字符串