2016-03-23 11 views
1

のマップを実行しますか?Scalaは、</p> Aは、対応する将来の実行の結果である <pre><code>Map[String, A] </code></pre> <p>に</p> <pre><code>Map[String, Future[A]] </code></pre> <p>から行くための最善の方法は何先物

これはコンパイルされません。

val results = for { 
    (key, future) <- myMap 
    result <- future 
} yield (key, result) 

私は理解のために同じで先物や反復可能オブジェクトを混在させることはできませんよう。おそらく、このような

+2

あなたは 'Map [String、Future [A]]'から 'Map [String、A]'に行くことを選択するしかないが、ブロックすることを認識していますか?あなたの場合はそれでいいですか?そうでなければ、あなたが本当に望んでいるのは 'Map [String、Future [A]]'から 'Future [Map [String、A]]' –

+0

@RégisJean-Gillesの良い発言です。この[回答](http://stackoverflow.com/questions/17479160/how-to-convert-mapa-futureb-to-futuremapa-b)には、これを行うためのヒントも含まれています。 – ticofab

答えて

2

あなたはSeq[Future[(String,A)]]に変換する場合は、その後、単一Future[Map[...]]それを取り戻すためにFuture.foldを使用することができます。

def transform[A](m: Map[String, Future[A]]): Future[Map[String, A]] = { 
    val seq: Seq[Future[(String, A)]] = m.toSeq.map { case (key, f) => 
    f.map(i => key -> i) 
    } 

    Future.fold(seq)(Map.empty[String, A])(_ + _) 
} 

はその後、通常のように、単一の未来を買い戻します。

0

何か:

map.mapValues { Await.result(_, 5 seconds) } 
+0

2番目の選択肢はコンパイルされません。 –

+0

それを取り除く。 – Dima

-1

ディマはすでにAwaitを使用して答えを与えました。しかし、未来が失敗したときに例外が発生します。

さらに型をTryとしてラップしてから、.collectを実行して、正常なFuturesのみをフィルタリングすることができます(公式APIをチェックしてください)。

import scala.util.{ Try, Success } 

val results = myMap 
    .map { 
     case (key, value) => key => Try(Await.result(value, 5.seconds)) 
    } 
    .collect { 
     case (key, Success(value)) => key -> value 
    } 

上記の呼び出しでは、失敗した先物は自動的に破棄され、成功したもののみが回収されます。

+0

これは動作しません。マップ内の値は 'Future'型で、' Success'と互換性がありません。問題は、未来から実際の(「現在」の)結果に到達するためには、ブロックしてどこかを待たなければならないということです。 – Dima

+0

実際、Aha。今回は試してみるよ。私は私の答えを編集しました。 'collect'はあなたがどこかで結果を取得して実際の' Try'に変換した後にのみ動作します。 – bow

関連する問題