549

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?

4
  • 54
    Perhaps Array.from(Map.keys()). Commented Feb 11, 2016 at 14:20
  • stackoverflow.com/questions/8763125/get-array-of-objects-keys Commented Feb 11, 2016 at 14:20
  • 5
    @gK. It doesn't work with Map. Commented Feb 11, 2016 at 14:20
  • 19
    Array.from(Map.values()) - if in case, you need values, instead of keys. Commented Jun 22, 2020 at 20:21

7 Answers 7

947

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"]
Sign up to request clarification or add additional context in comments.

11 Comments

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.
@Cody that's because your slice() invocation is being executed before the spread operator. Try [ ... Array.from(map.values()).slice(0) ]
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.
@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.
@pawel ..."abc" nor ...("abc") are working in the chrome console, which supports ES6?
|
33

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)

Comments

17

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

Comments

9

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

Comments

7

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"]

1 Comment

Unfortunately, this seems to only work if you use --downlevelIteration :(
2

Side note, if you are using a JavaScript object instead of a map, you can use Object.keys(object) which will return an array of the keys. Docs: link

Note that a JS object is different from a map and can't necessarily be used interchangeably!

1 Comment

Upvoted because often an object is all you need.
0

If You want extract keys and iterate over key map, You can do both operatrion in one line:

for (const i of Object.keys(myMap )) {
       console.log(i)
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.