Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Convert ES6 Map to Object Literal
let map = new Map();
map.set("a", 1);
map.set("b", 2);
map.set("c", 3);
let obj = Array.from(map).reduce((obj, [key, value]) => (
Object.assign(obj, { [key]: value }) // Be careful! Maps can have non-String keys; object literals can't.
), {});
console.log(obj); // => { a: 1, b: 2, c: 3 }
@lukehorvat

This comment has been minimized.

Copy link
Owner Author

lukehorvat commented Apr 8, 2015

You can also do this inside a custom toJSON method defined for the Map instance, so that it automatically takes place whenever JavaScript's JSON.stringify function is called.

@Mike-Tran

This comment has been minimized.

Copy link

Mike-Tran commented May 9, 2018

Instead of converting the map -> array -> iterating over array / filling in new object

Could you do this?

const convertMapsToObjects = (mapInstance) => {
  const obj = {};
  for(let prop of map){
    obj[prop[0]] = prop[1];
  }
 return obj;
}

http://jsben.ch/mGhq1

Thanks for sharing!

@goldhand

This comment has been minimized.

Copy link

goldhand commented May 25, 2018

Major performance hit when you create a new object (with Object.assign) inside every iteration.

Because you're creating a new object literal when you call Array.reduce(fn, {}), you can safely mutate that accumulator object from within the reducer function.

This is WAYYYYY faster:

let obj = Array.from(map).reduce((obj, [key, value]) => {
  obj[key] = value;
  return obj;
}, {});

Unfortunately, you'll never know because gist doesn't send comment notifications... I hope someone finds this comment and it helps them. Email me if it does, so I can be notified this helped someone 😉

@changbowen

This comment has been minimized.

Copy link

changbowen commented Jun 4, 2018

I think with ES6 if you replace Array.from(map) with [...map.entries()], it's even faster :)
Could also be a one-liner:
let obj = [...map.entries()].reduce((obj, [key, value]) => (obj[key] = value, obj), {});

@IllusionElements

This comment has been minimized.

Copy link

IllusionElements commented Jun 4, 2018

This would be the best way

  const obj = map.entries().reduce((main, [key, value]) => ({...main, [key]: value,{})
@jlyonsmith

This comment has been minimized.

Copy link

jlyonsmith commented Jun 19, 2018

@IllusionElements almost has it. reduce only exists on Array, so you have to convert the map.entries() from an iterator first. And there are some brackets missing:

const obj = Array.from(map.entries()).reduce((main, [key, value]) => ({...main, [key]: value}), {})

Will do the trick. @changbowen has the right answer too if you want to use the spread operator instead of Array.from().

@gwillz

This comment has been minimized.

Copy link

gwillz commented Jul 23, 2018

Doing a spread operator in the loop {...main, [key]: value} is as inefficient as Object.assign() in the OP.
In contrast; obj[key] = value is simply modifying the reducer sum value, rather than recreating it on every loop.
The ES6 spread operator is indeed faster than Array.from(), but is still slower than the for of loop.

TL:DR; crude results below at 100,000 iterations of a 15 element map.

fromAssign: 1255.439ms
forOf: 109.349ms
fromReuse: 369.059ms
spreadReuse: 237.935ms
fromSpread: 4260.636ms
spreadSpread: 4094.880ms
@seromenho

This comment has been minimized.

Copy link

seromenho commented Apr 4, 2019

With for...of

const obj = {};
for (let [key, value] of map) {
  obj[key] = value;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.