3

I'm merging these maps :

val map1 : Map[String, String] = Map("four" -> "1", "three" -> "2");
val map2 : Map[String, String] = Map("four" -> "3", "three" -> "4");
val map3 : Map[String, String] = Map("four" -> "5", "three" -> "6");
val map4 : Map[String, String] = Map("four" -> "7", "three" -> "8");

using loops and mutable variables.

I'm not sure how to write a functional implementation ?

Complete code :

object tryout extends App {

val map1 : Map[String, String] = Map("four" -> "1", "three" -> "2");
val map2 : Map[String, String] = Map("four" -> "3", "three" -> "4");
val map3 : Map[String, String] = Map("four" -> "5", "three" -> "6");
val map4 : Map[String, String] = Map("four" -> "7", "three" -> "8");

val mapList : List[Map[String , String]] = List(map1 , map2 , map3 , map4)

val mergedMap: Map[String, List[String]] = Map("three" -> List("2","4","6","8") , 
                    "four" -> List("1","3","5","7"));

 val map = new scala.collection.mutable.HashMap[String,ListBuffer[String]]()
mapList.map(m => {

  m.map(m2 => {
    if(map.contains(m2._1)){
      val lb = map.get(m2._1).get
      lb += m2._2
    }
    else {
      map.put(m2._1, ListBuffer(m2._2))
    }
  })


})

map.foreach(m => println(m._1+","+m._2.mkString(",")))

}
1

1 Answer 1

4

This is a one liner but you can break it up as you please:

mapList.flatten.groupBy(_._1).mapValues(x => x.map(y => y._2))

Result:

res0: scala.collection.immutable.Map[String,List[String]] = 
Map(three -> List(2, 4, 6, 8), four -> List(1, 3, 5, 7))

In functional programming, explicit looping is avoided; we attempt to achieve the same using combinators like flatMap, map... Also, if you start thinking of a Map in Scala as a 2-tuple (which is what it is underneath) then dealing with them becomes much more intuitive in my opinion. This -> is just an implicit defined in the Prelude to make Map definitions easier on the eye.

5
  • thanks, should be type scala.collection.immutable.Map[String,List[String]] , not scala.collection.immutable.Map[String,List[Char]] ? The values may not always be single chars.
    – blue-sky
    Commented Aug 21, 2015 at 19:10
  • You can replace .flatMap(identity) with .flatten. Commented Aug 21, 2015 at 19:30
  • @Chris Martin same result - Char is still mapped
    – blue-sky
    Commented Aug 21, 2015 at 19:42
  • @blue-sky I'm just trying to shorten the code, not change the result. Commented Aug 21, 2015 at 20:04
  • @blue-sky, fixed, see new solution.
    – user3248346
    Commented Aug 21, 2015 at 20:36

Not the answer you're looking for? Browse other questions tagged or ask your own question.