LoginSignup
11
7

More than 5 years have passed since last update.

Seq[Future[A]]を Success のみの結果からなる Future[Seq[A]] に変換する

Last updated at Posted at 2015-10-15

以下の f1~f5 をひとつの Future[Seq[Int]] にしたいとする。

    val f1 = Future.successful(1)
    val f2 = Future.successful(2)
    val f3 = Future.failed(new UnsupportedOperationException("f3"))
    val f4 = Future.failed(new UnsupportedOperationException("f4"))
    val f5 = Future.successful(5)
    val fs = Seq(f1, f2, f3, f4, f5)

scala.concurrent.Future.sequence を使用すると、Failure が含まれていた場合最終的な結果が Failure となる。

    val r = Future.sequence(Seq(f1, f2, f3, f4, f5))
    r onComplete {
      case Success(ns) => println(ns)
      case Failure(t) => t.printStackTrace()
    }
    // java.lang.UnsupportedOperationException: f3

結果が Failure になる要素は除き、Success になる要素のみの Seq を得たい場合、どうするのがいいか。
このような関数を書いてみた。

  def sequence[A](f: Future[A]*)(implicit ex: ExecutionContext): Future[Seq[A]] = {
    Future.sequence(f.map(_.map(Some(_)).recover { case t => None })).map(_.flatten)
  }

これを使うと、欲しい結果は得られた。

    val r = sequence(f1, f2, f3, f4, f5)
    r onComplete {
      case Success(ns) => println(ns)
      case Failure(t) => t.printStackTrace()
    }
    // ArrayBuffer(1, 2, 5)

…が、もっと簡潔な書き方があったり、標準ライブラリにこれを実現する関数が用意されていたりするだろうか?

11
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
7