映射列表的Scala未来

时间:2013-11-26 12:57:45

标签: scala future

我有一份期货清单,我想逐一转换:

def foo(x: A): Future[B] = {...}
def mapFutures(xs: Future[List[A]]): Future[List[B]]

函数mapFutures应使用foo转换列表的每个元素,并返回列表的未来。最好的方法是什么?

3 个答案:

答案 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 }

<击>


编辑(基本上与cmbaxter相同;只是没有for-comprehension)。

对于未来,您希望平面映射序列。序列将期货列表转换为列表的未来。

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)