Yield a sequence of tuples instead of map

738 views Asked by At

This is my code. To my surprise, it yields a map instead of a seq of tuples as I expect. What is right way to get list of tuples in scala?

for ((_, s) <- Constants.sites;
         line <- Source.fromFile(s"data/keywords/topkey$s.txt").getLines
    ) yield ((s, line))
2

There are 2 answers

3
Akos Krivachy On

The reason probably is that Constants.sites is a Map, therefore it returns a map.

Instead of running the comprehension over Constants.sites, run it over Constants.sites.values, you are only using the values anyway.

The background is that your code gets translated to:

Constants.sites.flatMap {
  case (_, s) =>
    Source.fromFile(s"data/keywords/topkey$s.txt").getLines.map {
       line =>
         (s, line)
    }
}

And when calling flatMap on Map your resulting type also needs to be a Map, and the tuples can be coerced to a Map.

EDIT: But using this should be fine:

for {
  (_, s) <- Constants.sites
  line <- Source.fromFile(s"data/keywords/topkey$s.txt").getLines
) yield ((s, line))
0
fredfred On

You could convert any Map to a Seq like this:

scala> val m = Map(1->"one", 2 -> "two")
m: scala.collection.immutable.Map[Int,String] = Map(1 -> one, 2 -> two)

scala> m.toSeq
res0: Seq[(Int, String)] = ArrayBuffer((1,one), (2,two))

In your case you might do

val result = for ((_, s) <- Constants.sites;
         line <- Source.fromFile(s"data/keywords/topkey$s.txt").getLines
    ) yield ((s, line))
result.toSeq