Ricardo Piccoli
Ricardo Piccoli

Reputation: 491

How to flatten a sequence within a case class

In Scala, is it possible to use flatmaps more efficiently with case classes containing arrays to be exploded?

Here is a code that works, but doesn't look right:

object stuff {
    def main(args: Array[String]): Unit = {
        case class Stuff(name: String, stuff: Seq[String])
        case class FlatStuff(name: String, stuff: String)

        val someStuff = Array(Stuff("a", Seq("1", "2", "3")), Stuff("b", Seq("4", "5")))

        val stuffs = someStuff.flatMap(item => {
            val flatten = new Array[FlatStuff](item.stuff.length)
            for (i <- 0 until item.stuff.length) {
                flatten(i) = FlatStuff(item.name, item.stuff(i))
            }
            flatten
        })

        stuffs.foreach(stuff => println(stuff))
    }
}

Upvotes: 1

Views: 911

Answers (1)

Maybe a simple for comprehension will be more readable:

val stuffs = for {
  Stuff(name, stuffArray) <- someStuff // for each name & struffArray in someStuff.
  stuff <- stuffArray // for each stuff in stuffArray.
} yield FlatStuff(name, stuff) // Return a new FlatSutff.

As @user6337 explain in the comments, the for comprehension is just sugar syntax for map & flatMap.
Thus, the above can be rewritten as:

someStuff.flatMap {
  case Stuff(name, stuffArray) =>
    stuffArray.map {
      stuff => FlatStuff(name, stuff)
    }
}

Upvotes: 5

Related Questions