List[Future[List[Int]]] 到 List[Int]

List[Future[List[Int]]] to List[Int]

有了大List[Int],我决定用List#grouped(Int)得到一个List[List[Int]]。然后,我映射它,应用一个函数,List[Int] => Future[List[Int]]。我的意图是同时对子列表应用一个函数。

现在我有 List[scala.concurrent.Future[List[Int]]].

鉴于这种类型,我想List[Int]收集结果。

执行此操作的惯用方法是什么?

我假设您指的是 Future[List[Int]] 而不仅仅是 List[Int]。在这种情况下,您将使用 Future.sequenceList[Future[A]] 映射到 Future[List[A]],然后 flatten 单个 Future 中包含的 List

val list: List[Future[List[Int]]] = ...

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

如果出于某种原因只想删除 Future,那么您需要阻止才能获得它。

Await.result(Future.sequence(list).map(_.flatten), Duration.Inf)
val futures = List[Future[List[Int]]]
Future.fold(futures)(List.empty) { (l, r) =>
    l ++ r
} onComplete {
    case Success(r) => println(r)
    case Failure(e) => e.printStackTrace()
}

@m-z 建议的 sequence 方法会起作用,但是 cool/idiomatic 方法是使用 scalaz 的 traverseM 而不是 map 的函数:

def myFunction(li: List[Int]): Future[List[Int]] = ...
val myList: List[List[Int]] = ...

import scalaz._, Scalaz._

myList.traverseM(myFunction) //returns a Future[List[Int]]