Convert Map to JSON object in Javascript

2020-02-25 07:19发布

问题:

So Ive got the following javascript which contains a key/value pair to map a nested path to a directory.

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

Now what I want to do is create a JSON object from the key in the map.

It has to be,

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

Not sure if there is an out of a box way to do this. Any help is appreciated.

回答1:

You could loop over the map and over the keys and assign the value

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



回答2:

Given in MDN, fromEntries() is available since Node v12:

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

const obj = Object.fromEntries(entries);

console.log(obj);
// expected output: Object { foo: "bar", baz: 42 }


回答3:

I hope this function is self-explanatory enough. This is what I used to do the job.

/*
 * 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)


回答4:

Another approach. I'd be curious which has better performance but jsPerf is down :(.

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

Without recursion:

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