Georg Heiler
Georg Heiler

Reputation: 17676

scala combining multiple sequences

I have a couple of lists:

val aa = Seq(1,2,3,4)
val bb = Seq(Seq(2.0,3.0,4.0,5.0), Seq(1.0,2.0,3.0,4.0))
val cc = Seq("a", "B")

And want to combine them in the desired format of:

(1, 2.0, a), (2, 3.0, a), (3, 4.0, a), (4, 5.0, a), (1, 1.0, b), (2, 2.0, b), (3, 3.0, b), (4, 4.0, b)

but my combination of zip and flatMap

(aa, bb,cc).zipped.flatMap{
  case (a, b,c) => {
    b.map(b1 => (a,b1,c))
  }
}

is only producing

(1,2.0,a), (1,3.0,a), (1,4.0,a), (1,5.0,a), (2,1.0,B), (2,2.0,B), (2,3.0,B), (2,4.0,B)

In java I would just iterate for over bb and then again in a nested loop iterate over the values.

What do I need to change to get the data in the desired format using neat functional scala?

Upvotes: 2

Views: 955

Answers (3)

Puneeth Reddy V
Puneeth Reddy V

Reputation: 1568

Another approach using collect and map

scala> val result = bb.zip(cc).collect{
  case bc => (aa.zip(bc._1).map(e => (e._1,e._2, bc._2)))
}.flatten
result: Seq[(Int, Double, String)] = List((1,2.0,a), (2,3.0,a), (3,4.0,a), (4,5.0,a), (1,1.0,B), (2,2.0,B), (3,3.0,B), (4,4.0,B))

Upvotes: 0

Andrey Tyukin
Andrey Tyukin

Reputation: 44908

How about this:

for {
  (bs, c) <- bb zip cc
  (a, b) <- aa zip bs
} yield (a, b, c)

Produces:

List(
  (1,2.0,a), (2,3.0,a), (3,4.0,a), (4,5.0,a), 
  (1,1.0,b), (2,2.0,b), (3,3.0,b), (4,4.0,b)
)

I doubt this could be made any more neat & functional.

Upvotes: 3

Xavier Guihot
Xavier Guihot

Reputation: 61656

Not exactly pretty to read but here is an option:

bb
  .map(b => aa.zip(b)) // List(List((1,2.0), (2,3.0), (3,4.0), (4,5.0)), List((1,1.0), (2,2.0), (3,3.0), (4,4.0)))
  .zip(cc) // List((List((1,2.0), (2,3.0), (3,4.0), (4,5.0)),a), (List((1,1.0), (2,2.0), (3,3.0), (4,4.0)),B))
  .flatMap{ case (l, c) => l.map(t => (t._1, t._2, c)) } // List((1,2.0,a), (2,3.0,a), (3,4.0,a), (4,5.0,a), (1,1.0,B), (2,2.0,B), (3,3.0,B), (4,4.0,B))

Upvotes: 1

Related Questions