Elegant way to invert a map in Scala

前端 未结 10 564
慢半拍i
慢半拍i 2020-12-02 13:49

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:



        
10条回答
  •  伪装坚强ぢ
    2020-12-02 14:48

    We can try using this foldLeft function that will take care of collisions and invert the map in single traversal.

    scala> def invertMap[A, B](inputMap: Map[A, B]): Map[B, List[A]] = {
         |     inputMap.foldLeft(Map[B, List[A]]()) {
         |       case (mapAccumulator, (value, key)) =>
         |         if (mapAccumulator.contains(key)) {
         |           mapAccumulator.updated(key, mapAccumulator(key) :+ value)
         |         } else {
         |           mapAccumulator.updated(key, List(value))
         |         }
         |     }
         |   }
    invertMap: [A, B](inputMap: Map[A,B])Map[B,List[A]]
    
    scala> val map = Map(1 -> 2, 2 -> 2, 3 -> 3, 4 -> 3, 5 -> 5)
    map: scala.collection.immutable.Map[Int,Int] = Map(5 -> 5, 1 -> 2, 2 -> 2, 3 -> 3, 4 -> 3)
    
    scala> invertMap(map)
    res0: Map[Int,List[Int]] = Map(5 -> List(5), 2 -> List(1, 2), 3 -> List(3, 4))
    
    scala> val map = Map("A" -> "A", "B" -> "A", "C" -> "C", "D" -> "C", "E" -> "E")
    map: scala.collection.immutable.Map[String,String] = Map(E -> E, A -> A, B -> A, C -> C, D -> C)
    
    scala> invertMap(map)
    res1: Map[String,List[String]] = Map(E -> List(E), A -> List(A, B), C -> List(C, D))
    

提交回复
热议问题