Nick Allen
Nick Allen

Reputation: 1467

Map Over the Keys/Values from an Option[Map]

I am trying to extract they keys/values from an Option[Map]. What is the simplest way to iterate over the key/values contains in the Map, only if the Option actually has a Map?

Here is a simple example that highlights my problem.

val values = Option(Map("foo" -> 22, "bar" -> 23))
values map { case (key, value) => println(s"$key = $value") }  

This fails to compile.

 <console>:12: error: constructor cannot be instantiated to expected type;
 found   : (T1, T2)
 required: scala.collection.immutable.Map[String,Int]
              values map { case (key, value) => println(s"$key = $value") }
                                ^

If the Map is not wrapped in an Option, then it works just fine.

val values = Map("foo" -> 22, "bar" -> 23)
values map { case (key, value) => println(s"$key = $value") }

Upvotes: 2

Views: 1161

Answers (2)

LRLucena
LRLucena

Reputation: 1705

You can use getOrElse to unwrap the Map.

val values = Option(Map("foo" -> 22, "bar" -> 23))
values getOrElse Map() foreach { case (key, value) => println(s"$key = $value") }  

Upvotes: 2

Michael Zajac
Michael Zajac

Reputation: 55569

You need another map, because the first map is for the Option, which means the your lambda is trying to match a single key-value pair, when it's really the full Map contained in the Option.

values.map(a => ???)
           ^ This is a Map[String, Int]

Syntactically, you want this:

values.map(_.map { case (key, value) => println(s"$key = $value") })

But this isn't really a map in it's true sense, it's more like a foreach since it only produces a side-effect.

values.foreach(_.foreach { case (key, value) => println(s"$key = $value") })

Or with a for-comprehension:

for {
    map <- values
    (key, value) <- map
} println(s"$key = $value")

Upvotes: 5

Related Questions