Reputation: 185
I have Future[MyType] and I need to pass the value of MyType to a method which returns Seq[Future[MyType]], so basic signature of problem is:
val a: Seq[Future[MyType]] = ...
getValue(t: MyType): Seq[Future[MyType]] = {...}
I want to pass value of a to getValue. I tried something like:
val b:Seq[Future[MyType]] = a.map{v => getValue(v)}
I want b to be of Seq[Future[MyType]]
type
but, it obviously didn't worked as v is of type Future[MyType] and getValue needs only MyType as parameter. What could be a possible solution??
Upvotes: 0
Views: 68
Reputation: 18424
You can do:
val b = a.map(_.map(getValue(_)))
This will give you a Seq[Future[Seq[Future[MyType]]]]
. That's pretty ugly. There are three tools that can make that better.
Future.sequence
takes a Seq[Future[A]]
and gives you a Future[Seq[A]]
. The output future will wait for all input futures to complete before giving a result. This might not always be what you want.fut.flatMap
takes a function computing a Future
as a result but does not return a nested Future, as would happen with .map
..flatten
on a Seq[Seq[A]]
to get a Seq[A]
Putting this all together, you could do something like:
val b: Seq[Future[Seq[MyType]] = a.map(_.flatMap(x => Future.sequence(getValue(x))))
val c: Future[Seq[MyType]] = Future.sequence(b).map(_.flatten)
More generally, when dealing with "container" types, you'll use some combination of map
and flatMap
to get at the inner types and pass them around. And common containers often have ways to flatten or swap orders, e.g. A[A[X]] => A[X]
or A[B[X]] => B[A[X]]
.
Upvotes: 3