Avba
Avba

Reputation: 15266

scala - how to flatten nested optional when using for loop with futures

I'm performing a for loop on a range which yields a future of an optional result. I want the resulting collection to only contain non-optional items .

But I'm left instead with Future[Seq[Option[Result]]]

The code looks similar to this:

val result = for {
        x <- 0 to numItems
      } yield {
        Future{
          ...logic...
          val intermediateResult: Option[Thing] = SomethingWhichReturnsOptionOfThing
          val s: Option[String] = intermediateResult map {
            ir => ...Do something with ir when it exists and then and map to String...
          }
          s map {
            string => Result(x, string)
          }
        }
      }
      Future.sequence(result) // Future[Seq[Option[Result]]]

But what i want is all the results without the Option i.e. Future[Seq[Result]]

Upvotes: 0

Views: 596

Answers (2)

Tim
Tim

Reputation: 27356

You can flatten the Seq once the Future has completed:

Future.sequence(result).map(_.flatten)

This will remove all None values and extract the Result value from all Some results.

Note that you will no longer know which Result came from which item number, and Future.sequence may discard some errors as well, so this is not the best solution if you want accurate error handling/reporting.

Upvotes: 2

Terry Dactyl
Terry Dactyl

Reputation: 1868

Flatten the contents of the future.

scala> List(Some(1), None, Some(2))
res1: List[Option[Int]] = List(Some(1), None, Some(2))

res1.flatten
res2: List[Int] = List(1, 2)

Upvotes: 1

Related Questions