type mismatch compiler error when concatenating two maps using getOrElse

390 views Asked by At

I'm trying to concatenate a mutable with an immutable map in scala.

case class Result(val key: String, val number: Int)

object Test extends App {

  val map1 = scala.collection.mutable.Map[String, List[Result]]()
  val map2: Map[String, List[Result]] = Map("test" -> List(new Result("0", 0)))

  map1 ++= map2.map(c => (c -> (c._2 + map1.getOrElse(c._1, List[Result]()))))

}

But compiler always says:

type mismatch;  found   : List[Result]  required: String

When i change ListResult to "test" compiler says:

type mismatch;  found   : java.io.Serializable  required: String

I'm quite confused. Do I use getOrElse the wrong way?

regards Cyrill

1

There are 1 answers

0
The Archetypal Paul On BEST ANSWER
map1 ++= map2.map(c => (c -> (c._2 + map1.getOrElse(c._1, List[Result]()))))

map on a Map gets passed each element of the Map. So c is a (String, List[Result]). So this

(c -> (c._2 + map1.getOrElse(c._1, List[Result]()))

is ((String, List[Result), (List[Result]). Which is wrong. I imagine you meant

(c._1 -> (c._2 + map1.getOrElse(c._1, List[Result]()))

but that still has a type mismatch. I think you're hitting the fairly common problem of the implicit Any2String for +, and the compiler wants a String where it shouldn't.

Anyway,

(c._1 -> (c._2 ++ map1.getOrElse(c._1, List[Result]()))

seems to work

map1 ++= map2.map(c => (c._1 -> (c._2 ++ map1.getOrElse(c._1, List[Result]()))))

Also, Nil is a bit neater:

map1 ++= map2.map(c => (c._1 -> (c._2 ++ map1.getOrElse(c._1, Nil))))

and clearer again (IMO) is the for comprehension

for ((k,v) <-map2) map1 += (k-> (v ++ map1.getOrElse(k, Nil)))