Reputation: 3776
I was wondering, what is the most convenient way to invert keys and values in a Map. Is there any builtin method or should it be done by iterating over keys and values?
const map: Map<string, number> = new Map()
const inverse: Map<number, string>
Upvotes: 23
Views: 18101
Reputation: 351288
You could pass the inverse tuples to the constructor, using Array.from
and Array#reverse
:
new Map(Array.from(origMap, a => a.reverse() as [number,string]))
See it run on an example:
const origMap = new Map([["a", 1],["b", 2]]);
console.log(...origMap);
// Reverse:
const inv = new Map(Array.from(origMap, a => a.reverse()));
console.log(...inv);
Specific for TypeScript: even though a
is of the type [string, number]
, TypeScript does not regard a.reverse()
to be of of the type [number, string]
, but as the more generic (string | number)[]
, which is not the type of pairs we need for the Map
constructor argument.
The addition of as [number, string]
deals with that. In plain JavaScript you would leave that out.
Upvotes: 36
Reputation: 57344
You can use the spread operator on your original map to obtain key-value array pairs which you can .map
to swap each pair. Lastly, dump the result into the Map
constructor for your copy. Any duplicate keys will be lost.
const orig = new Map([["a", 1], ["b", 2]]);
const cpy = new Map([...orig].map(e => e.reverse()));
console.log([...orig]);
console.log([...cpy]);
This is terse but does involve an extra array creation as pointed out by the inimitable trincot. That's only an issue if the maps are large.
By the way, if your original values are indeed numbers and aren't sparse, consider using a plain old array for your "flipped" map. This might improve performance and semantics, entirely dependent on your use case.
Upvotes: 5
Reputation: 85191
Given the assumption that there are no duplicate values, you can do an inverse like this:
const map: Map<string, number> = new Map();
map.set('3', 3);
map.set('4', 4);
const inverse: Map<number, string> = new Map();
map.forEach((value, key) => inverse.set(value, key));
Upvotes: 6