user2662833
user2662833

Reputation: 1073

Destructuring a Map

If I have an object in javascript like this:

let obj = {b: 3, c: 4, d: 6}

I can get the different parts out pretty easily if I destructure it, for example, I could just get c and d if I do:

let {c, d} = obj

Now this is great, but if I wanted to make a map:

let m = new Map()
m.set('b', 3).set('c', 4).set('d', 6)

I can get individual elements out with:

let c = m.get('c')
let d = m.get('d')

But is there any way to destructure an object like a map in the way that we did with a standard object. I find the syntax above so much simpler to use in many cases, that it actually serves as a pretty big disadvantage when using maps; despite the fact that you can get iterators by default and so on (list advantages here haha).

Upvotes: 18

Views: 37790

Answers (10)

ARiyou Jahan
ARiyou Jahan

Reputation: 1039

Let's say you have following map. You have 2 ways to destruct it:

const map = new Map();
map.set('a', 1)
   .set('b', 2)
   .set('c', 3);

1.Destructuring by key (like objects):

Fist convert Map to normal object using Object.fromEntries(map):

const {a, b, c } = Object.fromEntries(map);

2.Destructuring by [key, value] pairs (like arrays):

since this destructing syntax works with any iterable and Mapa are iterable as well we can do:

const [[keyA,a], [keyB,b], [keyC,c]] = map;

In this systanx we first destruct map to an array with each index representing a key, value pairs of each element in map. then we furthure destruct each index to [keyA, valueA].

we can do the same for Set as well (since it share same syntaxt as map in iteration).

Upvotes: 0

Bruce
Bruce

Reputation: 112

Construct Object.fromEntries and destructor it:

const map = new Map();
map.set('a', 3)
   .set('b', 4)
   .set('c', 6);

// to destructure
const {a, b, c } = Object.fromEntries(map);
console.log("a:", a, ", b:", b, ", c:", c); // a: 3 , b: 4 , c: 6

MDN documentation is here

Upvotes: 2

Marshal
Marshal

Reputation: 4860

It's actually quite easy. In your code example,

let m = new Map()
m.set('b', 3).set('c', 4).set('d', 6)

you can just:

let a = [...m] // => [ [ 'b', 3 ], [ 'c', 4 ], [ 'd', 6 ] ]

or

let a = [...m.entries()] // same as above, more verbose

If you want to destruct individual values into b, c, d, we could:

let [b, c, d] = [...m.values()]

This would be the same as @Salih's answer, but a bit more readable.

Upvotes: 1

const m = new Map();
m.set('b', 3)
 .set('c', 4)
 .set('d', 6);
 
const [[,b], [,c], [,d]] = m;

console.log(b, c, d);

const [[,b], [,c], [,d]] = m;

Upvotes: 12

Yehia Ahmed
Yehia Ahmed

Reputation: 1

const map = new Map([['a',1],['b',2],['c',3]]);

const arr = [...map.values()];

Upvotes: 0

dfsq
dfsq

Reputation: 193261

You can't destructure Map directly, you will have to either convert to object first or do something exotic, like using Proxy to intercept get calls. Something like this with helper function:

function getFromMap (map) {
  return new Proxy(map, {
    get (obj, prop) {
      return obj.get(prop)
    }
  })
}

let m = new Map()
m.set('b', 3).set('c', 4).set('d', 6)

let { b, d } = getFromMap(m)
console.log(b, d)

Thanks to @Felix Favour for comment. Using recent Object.fromEntries function intermediate conversion map to object can be simplified:

let { b, d } = Object.fromEntries(m)

Upvotes: 13

Kay
Kay

Reputation: 134

What about...

const mapAnObj = () => {
  const obj = { b: 3, c: 4, d: 6 }

  return Object.keys(obj).map(elem => obj[elem]);
};

console.log(mapAnObj());

Maybe I am not understanding the question correctly, correct me If I'm wrong but this would grant you the very same results, and it's effective and quick.

Upvotes: -2

gurvinder372
gurvinder372

Reputation: 68393

Convert Map to simple object first

var obj = [...m.entries()].reduce( (acc, c) => ( 
 acc[c[0]] = c[1], 
 acc), {}); //convert to object

Then you can destructure the same object

Demo

let m = new Map()
m.set('b', 3).set('c', 4).set('d', 6);

var obj = [...m.entries()].reduce( (acc, c) => ( 
 acc[c[0]] = c[1], 
 acc), {}); //convert to object

//console.log(obj);
let { c, d } = obj; 
console.log(c, d);

Upvotes: 3

Ori Drori
Ori Drori

Reputation: 191976

You can use a getMultiple() that returns an object with the keys you want, and then destructure the results:

const m = new Map([['b', 3], ['c', 4], ['d', 6]]);

const getMultiple = (m, ...keys) => Object.assign(...keys.map(k => ({ [k]: m.get(k) })))

const { b, d } = getMultiple(m, 'b', 'd')

console.log('b', b)
console.log('d', d)

Upvotes: 0

CertainPerformance
CertainPerformance

Reputation: 370699

There's no built-in way to destructure a Map, the only thing to do would be to explicitly convert it to an object first:

const m = new Map();
m.set('b', 3)
  .set('c', 4)
  .set('d', 6);
const { b, c, d } = mapToObj(m);
console.log(d);

function mapToObj(inputMap) {
  const obj = {};
  for (const [key, value] of m) obj[key] = value;
  return obj;
}

But if your keys are known beforehand, and aren't added/removed frequently, there might not be much benefit to using a Map - just use a standard Object instead and you can destructure natively.

Upvotes: 0

Related Questions