Omid
Omid

Reputation: 1989

TreeMap Keys and Iteration in Scala

I am using TreeMap and it behaves strangely in the following code.

Here is the code :

import scala.collection.immutable.TreeMap
object TreeMapTest extends App{

  val mp = TreeMap((0,1) -> "a", (0,2) -> "b", (1,3) -> "c", (3,4) -> "f")
  mp.keys.foreach(println) //A
  println("****")
  mp.map(x => x._1).foreach(println) //B
}

As you can see the two print lines (A and B) should have printed the same thing but the result is as follows:

(0,1)
(0,2)
(1,3)
(3,4)
****
(0,2)
(1,3)
(3,4)

Why is this happening here? The interesting thing is even the IDE believes that one can use these two interchangeably and suggests the replacement.

Upvotes: 2

Views: 668

Answers (1)

Alexey Romanov
Alexey Romanov

Reputation: 170745

Scala collection library generally tries to return the same kind of collection it starts with, so that e.g. val seq: Seq[Int] = ...; seq.map(...) will return a Seq, val seq: List[Int] = ...; seq.map(...) will return a List, etc. This isn't always possible: e.g. a String is considered to be a collection of Char, but "ab".map(x => x.toInt) obviously can't return a String. Similarly for Map: if you map each pair to a non-pair, you can't get a Map back; but you map each pair to a pair (Int, Int), and so Scala returns Map[Int, Int]. So you can't get both (0, 1) and (0, 2): they would be duplicate keys.

To avoid this problem, convert your map to Seq[((Int, Int), String)] first: mp.toSeq.map(x => x._1) (or mp.keySet.toSeq).

Upvotes: 3

Related Questions