Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elegant way to invert a map in Scala

Learning Scala currently and needed to invert a Map to do some inverted value->key lookups. I was looking for a simple way to do this, but came up with only:

(Map() ++ origMap.map(kvp=>(kvp._2->kvp._1))) 

Anybody have a more elegant approach?

like image 954
AlexeyMK Avatar asked Feb 25 '10 22:02

AlexeyMK


People also ask

Is scala map immutable?

By default, Scala uses the immutable Map. If you want to use the mutable Map, you'll have to import scala.

Is scala map a Hashmap?

Scala map is a collection of key/value pairs. Any value can be retrieved based on its key. Keys are unique in the Map, but values need not be unique.

Is scala map mutable?

Maps are classified into two types: mutable and immutable. By default Scala uses immutable Map. In order to use mutable Map, we must import scala.


2 Answers

Assuming values are unique, this works:

(Map() ++ origMap.map(_.swap)) 

On Scala 2.8, however, it's easier:

origMap.map(_.swap) 

Being able to do that is part of the reason why Scala 2.8 has a new collection library.

like image 199
Daniel C. Sobral Avatar answered Sep 20 '22 14:09

Daniel C. Sobral


Mathematically, the mapping might not be invertible (injective), e.g., from Map[A,B], you can't get Map[B,A], but rather you get Map[B,Set[A]], because there might be different keys associated with same values. So, if you are interested in knowing all the keys, here's the code:

val m = Map(1 -> "a", 2 -> "b", 4 -> "b") m.groupBy(_._2).mapValues(_.keys)  res0: Map[String,Iterable[Int]] = Map(b -> Set(2, 4), a -> Set(1)) 

Starting scala 2.13, this becomes even simpler and more efficient:

m.groupMap(_._2)(_._1) 
like image 28
Rok Kralj Avatar answered Sep 19 '22 14:09

Rok Kralj