我有一份期货清单,我想逐一转换:
def foo(x: A): Future[B] = {...}
def mapFutures(xs: Future[List[A]]): Future[List[B]]
函数mapFutures
应使用foo
转换列表的每个元素,并返回列表的未来。最好的方法是什么?
答案 0 :(得分:6)
你应该能够做你想做的事情(注意我将类型A和B指定为Int和String以使事情更容易理解):
def foo(x: Int): String = x.toString
def mapFutures(xs: Future[List[Int]]): Future[List[String]] = {
for(list <- xs) yield list map foo
}
现在,如果您想要更通用的内容,那么您可以像这样定义mapFutures
:
def mapFutures[A,B](xs: Future[List[A]], f:A => B): Future[List[B]] = {
for(list <- xs) yield list map f
}
然后就可以这样使用:
val futs = Future(List(1,2,3))
val mappedFuts = mapFutures(futs, foo)
修改强>
现在,如果foo返回Future
,你可以这样做:
def foo(x: Int): Future[String] = Future(x.toString)
def mapFutures[A,B](xs: Future[List[A]], f:A => Future[B]): Future[List[B]] = {
for{
list <- xs
mapped <- Future.sequence(list map f)
} yield mapped
}
答案 1 :(得分:1)
只是映射未来:
val futureList = Future.successful(List(1, 2, 3))
val mappedList = futureList map { _ map { _ + 1 } }
根据您的具体示例:
def foo(x: Int): String = x.toString
val fooList = fxs map { _ map foo }
击> <击> 撞击>
对于未来,您希望平面映射序列。序列将期货列表转换为列表的未来。
val fxs = Future(List(1, 2, 3))
def foo(x: Int): Future[String] = Future(x.toString)
val fooList = fxs flatMap { l => Future.sequence(l map foo) }
答案 2 :(得分:0)
您可以使用隐式类将flatMapSeq
扩展方法添加到Future[List[A]]
。
implicit class RichFutureSeq[A](val future: Future[List[A]]) extends AnyVal {
// def mapSeq[B](f: A => B): Future[List[B]] = future.map(_.map(f))
def flatMapSeq[B](f: A => Future[B]): Future[List[B]] = future.flatMap(Future.traverse(_)(f))
}
然后在您的客户端,您可以像这样使用它
// import the implicit if necessary
def foo(x: Int): Future[String] = Future.successful(x.toString)
val f : Future[List[Int]] = Future.successful(List(1, 2))
val fs: Future[List[String]] = f.flatMapSeq(foo)
def mapFutures(xs: Future[List[Int]])(f: Int => Future[String]): Future[List[String]] = xs.flatMapSeq(f)