Iterating over a map is slightly more complex than over other collections, because a Map is the combination of 2 collections. The keys and the values.

``````val m: Map[Int, String] = Map(1 -> "a", 2 -> "b")

m.keys    // = Iterable[Int] = Set(1, 2)
m.values  // = Iterable[String] = MapLike("a", "b")
``````

We make a Map using tuples. -> is just syntactic sugar for making a tuple.

``````val x = 1 -> 2                                     //  = (Int, Int) = (1,2)
val y = (1, 2)                                     //  = (Int, Int) = (1,2)
x == y                                             //  = Boolean = true
Map((1, "a"), (2, "b")) == Map(1 -> "a", 2 -> "b") //  = Boolean = true
``````

We get these tuples when we iterate over a Map.

``````m.foreach { a: (Int, String) =>
println(s"\$a")
}
``````

prints

``````(1,a)
(2,b)
``````

To get the key and the value we could use _1 and _2

``````m.foreach { a: (Int, String) =>
val key = a._1
val value = a._2
println(s"key:\$key value:\$value")
}
``````

But this looks confusing. It's better to unpack it using case.

``````m.foreach { case (k, v) =>
println(s"key:\$k value:\$v")
}
``````

We can use map to change the keys of a Map.

``````m.map { case (k, v) =>
k + 1 -> v
}
// = Map[Int,String] = Map(2 -> "a", 3 -> "b")
``````

If we just want to change the values, it's better to use mapValues.

``````m.mapValues { v => v + v }
// = Map[Int,String] = Map(1 -> "aa", 2 -> "bb")
``````

And of course our favorite method, flatMap, also works on Maps.

``````m.flatMap { case (k, v) =>
Map(k -> v, k + 10 -> v)
}
// = Map[Int,String] = Map(1 -> "a", 11 -> "a", 2 -> "b", 12 -> "b")
`````` 