I have a following Scala map and I want to reverse the map, for the duplicated new key, the value will be appended to a list.
For example
val map = Map(1 -> 111, 2 -> 222, 3 -> 111)
So the result of the map is
Map(111 -> List(1,3), 222 -> 2)
I have a following Scala map and I want to reverse the map, for the duplicated new key, the value will be appended to a list.
For example
val map = Map(1 -> 111, 2 -> 222, 3 -> 111)
So the result of the map is
Map(111 -> List(1,3), 222 -> 2)
You can use groupBy and mapValues
val map = Map(1 -> 111, 2 -> 222, 3 -> 111)
val result = map.groupBy { case (key, value) => value }.mapValues(_.keys.toList)
println(result)
// Map(222 -> List(2), 111 -> List(1, 3))
if you dont want a List when there is one element (like in your example)
val result2 = map.groupBy { case (_, value) => value }.mapValues(_.keys.toList match {
case x :: Nil => x
case xs => xs
})
println(result2)
// Map(222 -> 2, 111 -> List(1, 3))
groupBy value and map value to list of keys:
scala> val map = Map(1 -> 111, 2 -> 222, 3 -> 111)
map: scala.collection.immutable.Map[Int,Int] = Map(1 -> 111, 2 -> 222, 3 -> 111)
scala> map.groupBy(_._2).map{case (k, v) => k -> v.keys.toList}
res0: scala.collection.immutable.Map[Int,List[Int]] = HashMap(111 -> List(1, 3), 222 -> List(2))
Or, reverse
the map first with value -> key
and then groupBy new key,
scala> map.map {case (k, v) => List(v -> k) }
.groupBy { case List((a, b)) => a}
.map { case (k, v) => k -> v.flatten.map(_._2) }
res1: scala.collection.immutable.Map[Int,scala.collection.immutable.Iterable[Int]] = HashMap(111 -> List(1, 3), 222 -> List(2))