How to flatten a List of Futures in Scala
Asked Answered
R

1

38

I want to take this val:

val f = List(Future(1), Future(2), Future(3))

Perform some operation on it (I was thinking flatten)

f.flatten

And get this result

scala> f.flatten = List(1,2,3)

If the flatten method isn't appropriate here, that's fine. As long as I get to the result.

Thanks!

Reticle answered 3/11, 2014 at 15:19 Comment(2)
What do you want to happen if one of the Futures fails?Shanley
If any of the futures fail, then I want the whole thing to fail. This is part of a homework question, so I wasn't looking to get the whole thing solved for me. But basically, I still have to figure out how to determine if any of the futures failed and if they did, I just kill the whole thing.Reticle
T
81

Future.sequence takes a List[Future[T]] and returns a Future[List[T]].

You can do

Future.sequence(f) 

and then use map or onComplete on it to access the list of values.

Textile answered 3/11, 2014 at 15:24 Comment(6)
This is the output I'm getting: scala.concurrent.Future[List[Int]] = scala.concurrent.impl.Promise$DefaultPromise@3227f076 Is this expected? It is transforming a List[Future[T]] into a Future[List[T]]. But I was expecting something along the lines of: scala.concurrent.Future[List[Int]] = Future(List(1,2,3)) Thanks!Reticle
Yes, it's a Future. Now you can handle it (either map, use onComplete or anything you want). The result inside the Future will be your list in case of successTextile
Future doesn't normally print what's inside it (that would mean blocking). If you do Future(1), you'll get something that looks like scala.concurrent.impl.Promise$DefaultPromise@78393fdb. For testing you can use something like Await.result(f, 2.seconds).Dutybound
@mikejones1477 it's almost always preferable not to block. Consider handling the result asynchronouslyTextile
Yes. I wasn't planning on blocking for my final result. But in the interest of learning, I'd like to ask what you mean about asynchronously?Reticle
I mean in a non-blocking way. Mapping over a future is already asynchronous, since the code will run eventually in the future (if the computation has success)Textile

© 2022 - 2024 — McMap. All rights reserved.