EliSquared
EliSquared

Reputation: 1559

Expand a Sequence grouped by keys into a list of ungrouped sequences with keys attached in Scala

I have the following object in Scala:

List[(String,Map[String, Seq[(Int, Double)]])]

And I would like to convert it into a sequence of individual rows where each row of the sequence has 4 terms: (String,String,Int,Double).

For instance, if I had the following data:

List(
  ("SuperGroup1", Map("SubGroup1" -> Seq((17,24.1),(38,39.2)))),
  ("SuperGroup1", Map("SubGroup2" -> Seq((135,302.3),(938,887.4))))
)

I want to turn it into:

Seq(
  ("SuperGroup1","SubGroup1",17,24.1),
  ("SuperGroup1","SubGroup1",38,39.2),
  ("SuperGroup1","SubGroup2",135,302.3),
  ("SuperGroup1","SubGroup2",938,887.4)
)

I figure you can use flatMap or something like that, but I am not exactly sure how that would work. I see that RDDs have a function called flatMapValues, but what about for just a standard list/map combination like I have?

Upvotes: 0

Views: 70

Answers (2)

Andrey Tyukin
Andrey Tyukin

Reputation: 44908

Given

val x = List(
  ("SuperGroup1",Map("SubGroup1" -> Seq((17,24.1),(38,39.2)))),
  ("SuperGroup1",Map("SubGroup2" -> Seq((135,302.3),(938,887.4))))
)

you obtain the list that you want from

for ((s, m) <- x; (k, vs) <- m; (i, f) <- vs) yield (s, k, i, f)

Result:

List(
  (SuperGroup1,SubGroup1,17,24.1),
  (SuperGroup1,SubGroup1,38,39.2),
  (SuperGroup1,SubGroup2,135,302.3),
  (SuperGroup1,SubGroup2,938,887.4)
)

Upvotes: 2

Luca T.
Luca T.

Reputation: 1651

Given the types you have and the following input:

val input = Seq(
  ("SuperGroup1", Map("SubGroup1" -> Seq(((17,24.1),(38,39.2))))),
  ("SuperGroup1", Map("SubGroup2" -> Seq(((135,302.3),(938,887.4)))))
)

This would transform your input into the form you expect

input.flatMap { superGroupBox =>
  superGroupBox._2.toSeq.flatMap { subGroupBox =>
    subGroupBox._2.flatMap(x => Seq(x._1, x._2).map(numericTuple => (superGroupBox._1, subGroupBox._1, numericTuple._1, numericTuple._2)))
  }
}

Upvotes: 1

Related Questions