How to convert Map keys to array?

453,662

Solution 1

Map.keys() returns a MapIterator object which can be converted to Array using Array.from:

let keys = Array.from( myMap.keys() );
// ["a", "b"]

EDIT: you can also convert iterable object to array using spread syntax

let keys =[ ...myMap.keys() ];
// ["a", "b"]

Solution 2

You can use the spread operator to convert Map.keys() iterator in an Array.

let myMap = new Map().set('a', 1).set('b', 2).set(983, true)
let keys = [...myMap.keys()]
console.log(keys)

Solution 3

I need something similiar with angular reactive form:

let myMap = new Map().set(0, {status: 'VALID'}).set(1, {status: 'INVALID'});
let mapToArray = Array.from(myMap.values());
let isValid = mapToArray.every(x => x.status === 'VALID');

Solution 4

OK, let's go a bit more comprehensive and start with what's Map for those who don't know this feature in JavaScript... MDN says:

The Map object holds key-value pairs and remembers the original insertion order of the keys.
Any value (both objects and primitive values) may be used as either a key or a value.

As you mentioned, you can easily create an instance of Map using new keyword... In your case:

let myMap = new Map().set('a', 1).set('b', 2);

So let's see...

The way you mentioned is an OK way to do it, but yes, there are more concise ways to do that...

Map has many methods which you can use, like set() which you already used to assign the key values...

One of them is keys() which returns all the keys...

In your case, it will return:

MapIterator {"a", "b"}

and you easily convert them to an Array using ES6 ways, like spread operator...

const b = [...myMap.keys()];

Solution 5

Not exactly best answer to question but this trick new Array(...someMap) saved me couple of times when I need both key and value to generate needed array. For example when there is need to create react components from Map object based on both key and value values.

  let map = new Map();
  map.set("1", 1);
  map.set("2", 2);
  console.log(new Array(...map).map(pairs => pairs[0])); -> ["1", "2"]
Share:
453,662
Lilleman
Author by

Lilleman

Coding dude. Engines are also fun. :)

Updated on July 17, 2022

Comments

  • Lilleman
    Lilleman almost 2 years

    Lets say I have the following map:

    let myMap = new Map().set('a', 1).set('b', 2);
    

    And I want to obtain ['a', 'b'] based on the above. My current solution seems so long and horrible.

    let myMap = new Map().set('a', 1).set('b', 2);
    let keys = [];
    for (let key of myMap)
      keys.push(key);
    console.log(keys);

    There must be a better way, no?

  • Cody
    Cody over 6 years
    I like the use of the Spread Operator, though, my TypeScript transpiler throws this.map.values().slice is not a function. Maybe I should update.
  • mgthomas99
    mgthomas99 about 6 years
    @Cody that's because your slice() invocation is being executed before the spread operator. Try [ ... Array.from(map.values()).slice(0) ]
  • Stefan Rein
    Stefan Rein about 6 years
    TypeScript 2.7.2 says for this: const fooMap = new Map<number, string>(); const fooArray = [...fooMap.keys()]; the following: TS2461: Type 'IterableIterator<number>' is not an array type. So this is not allowed in TypeScript. Array.from works as expected.
  • pawel
    pawel about 6 years
    @StefanRein Typescript spread operator looks he same, but is not equivalent to the ES6 spread, as it only works with Array and Object types, whereas ES6 works with any iterable. You can e.g. do ..."abc" to get ["a","b","c"] in ES6, which is not possible in TS.
  • Stefan Rein
    Stefan Rein about 6 years
    @pawel ..."abc" nor ...("abc") are working in the chrome console, which supports ES6?
  • pawel
    pawel about 6 years
    @StefanRein sorry, [..."abc"], just like in the example with keys in my answer.
  • dleal
    dleal almost 3 years
    This doesn't work anymore, map.keys() will return an empty iterator. Instead, I'd suggest using Objects.keys(map), which returns an array with the keys
  • pawel
    pawel almost 3 years
    @dleal Do you have a link to ECMA specification that introduces such a backward-incompatible, breaking change? If it is true it should be added to my answer. As of now, in my case, Object.keys(map) returns an empty array.
  • dleal
    dleal almost 3 years
    I might be mistaken, because in developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… it appears as compatible. However, we're using JavaScript for our lambdas in AWS, and there the method is returning an empty array, with Object.keys() working