2014-05-10 30 views
1

說我已獲得期貨的列表,每一個鏈接到一些關鍵的:綁定額外的信息,未來的序列

val seq: Seq[(Key, Future[Value])] 

而我的目標是產生鍵值元組的列表,一旦所有期貨已完成:

val complete: Seq[(Key, Value)] 

我在想這是否可以使用序列調用來實現。例如,我知道我能做到以下幾點:

val complete = Future.sequence(seq.map(_._2).onComplete { 
    case Success(s) => s 
    case Failure(NonFatal(e)) => Seq() 
} 

但這隻會返回我的值對象的序列,我失去了鍵和值之間的配對信息。問題在於Future.sequence期待一系列期貨。

我該如何擴充這個以維持我的完整序列中的鍵/值配對?

感謝 德

回答

3

如何改變你的Seq[(Key, Future[Value])]Seq[Future[(Key, Value)]]第一。

val seq: Seq[(Key, Future[Value])] = // however your implementation is 

val futurePair: Seq[Future[(Key, Value)]] = for { 
    (key, value) <- seq 
} yield value.map(v => (key, v)) 

現在你可以使用序列得到Future[Seq[(Key, Value)]]

val complete: Future[Seq[(String, Int)]] = Future.sequence(futurePair) 
1

只是另一個答案的表達,使用unzipzip

scala> val vs = Seq(("one",Future(1)),("two",Future(2))) 
vs: Seq[(String, scala.concurrent.Future[Int])] = List((one,[email protected]), (two,[email protected])) 

scala> val (ks, fs) = vs.unzip 
ks: Seq[String] = List(one, two) 
fs: Seq[scala.concurrent.Future[Int]] = List([email protected], [email protected]) 

scala> val done = (Future sequence fs) map (ks zip _) 
done: scala.concurrent.Future[Seq[(String, Int)]] = [email protected] 

scala> done.value 
res0: Option[scala.util.Try[Seq[(String, Int)]]] = Some(Success(List((one,1), (two,2)))) 

或可能節省zippage:

scala> val done = (Future sequence fs) map ((ks, _).zipped) 
done: scala.concurrent.Future[scala.runtime.Tuple2Zipped[String,Seq[String],Int,Seq[Int]]] = [email protected] 

scala> done.value.get.get.toList 
res1: List[(String, Int)] = List((one,1), (two,2))