Reputation: 7502
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.
Upvotes: 96
Views: 198629
Reputation: 12206
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
& for...of
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 }
...spread
& destructuring assignment
& forEach
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 = {};
[...map].forEach(([key, value]) => (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
Upvotes: 37
Reputation: 11
var items = {1:"apple",2:"orange",3:"pineapple"};
let map = new Map(Object.entries(items)); //object to map
console.log(map);
const obj = new Object();
map.forEach((value,key)=> obj[key]=value); // map to object
console.log(obj);
Upvotes: 1
Reputation: 3261
Given in MDN, fromEntries()
is available since Node v12:
const map1 = new Map([
['foo', 'bar'],
['baz', 42]
]);
const obj = Object.fromEntries(map1);
// { foo: 'bar', baz: 42 }
For converting object back to map:
const map2 = new Map(Object.entries(obj));
// Map(2) { 'foo' => 'bar', 'baz' => 42 }
Upvotes: 203
Reputation: 239
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)
Upvotes: 22
Reputation: 5839
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);
Upvotes: 2
Reputation: 386858
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);
Upvotes: 15