【问题标题】:Mapping a Scala future of a list映射列表的 Scala 未来
【发布时间】:2017-07-04 15:52:11
【问题描述】:

我有一个期货列表,我想对其进行一一转换:

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

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

【问题讨论】:

  • 你说你想映射一个期货列表,但这是一个列表的未来。你是什​​么意思?
  • 后者 - 感谢您的澄清。

标签: scala future


【解决方案1】:

你应该能够像这样做你想做的事(注意我将类型 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
}

【讨论】:

  • 不完全- foo 应该返回 Future[B],而不仅仅是 B。在您的情况下,这使得 mapFutures[A, B] 具有返回类型 Future[List[Future[B]]] .
  • @thomson_matt,抱歉我错过了那部分,我更新了我的解决方案。
【解决方案2】:

只是描绘未来:

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 相同的方法;只是没有理解)。

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

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) }

【讨论】:

  • 不完全 - foo 应该返回一个 Future[String],而不仅仅是 String。
【解决方案3】:

您可以使用隐式类将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)

【讨论】:

    猜你喜欢
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-27
    • 1970-01-01
    • 1970-01-01
    • 2011-10-23
    相关资源
    最近更新 更多