I've a list of futures, which I'd like to transform one-by-one:
def foo(x: A): Future[B] = {...}
def mapFutures(xs: Future[List[A]]): Future[List[B]]
The function mapFutures
should transform each element of the list using foo
, and return a future of a list. What's the best way to do this?
You should be able to do what you want like this (note I specified the types A and B as Int and String to make things easier to understand):
def foo(x: Int): String = x.toString
def mapFutures(xs: Future[List[Int]]): Future[List[String]] = {
for(list <- xs) yield list map foo
}
Now if you wanted something more generic, then you could define mapFutures
like so:
def mapFutures[A,B](xs: Future[List[A]], f:A => B): Future[List[B]] = {
for(list <- xs) yield list map f
}
And then it could be used like this:
val futs = Future(List(1,2,3))
val mappedFuts = mapFutures(futs, foo)
EDIT
Now, if foo returned a Future
, you could do things like this:
def foo(x: Int): Future[String] = Future(x.toString)
def mapFutures[A,B](xs: Future[List[A]], f:A => Future[B]): Future[List[B]] = {
for{
list <- xs
mapped <- Future.sequence(list map f)
} yield mapped
}
Just map the future:
val futureList = Future.successful(List(1, 2, 3))
val mappedList = futureList map { _ map { _ + 1 } }
To your specific example:
def foo(x: Int): String = x.toString
val fooList = fxs map { _ map foo }
EDIT (basically the same approach as cmbaxter; just without the for-comprehension).
For a future, you want to flatMap the sequence. Sequence converts a list of futures into a future of a list.
val fxs = Future(List(1, 2, 3))
def foo(x: Int): Future[String] = Future(x.toString)
val fooList = fxs flatMap { l => Future.sequence(l map foo) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With