【问题标题】:How to convert a Twitter Future[Map[A, Future[C]]] to a Future[Map[A, C]]如何将 Twitter Future[Map[A, Future[C]]] 转换为 Future[Map[A, C]]
【发布时间】:2013-12-20 01:51:29
【问题描述】:

我正在尝试解决以下问题:

我有一个 Future[Map[A, B]]。对于所有 B,我需要应用将 B 转换为 Future[C] 的方法,并且我想返回 Future[Map[A, C]]

这是我目前的代码:

def getClients(clientIds: Seq[Int]): Future[Map[Int, ClientData]] = {

  def getClientData(clientInfo: ClientInfo): Future[ClientData] = 
    clientInfo match {
      case ValidInfo(info) => getData(info)
      case _ => throw new Exception
    }

  client.getClients(clientIds) map {
    _.toMap map {
      case (clientId: Int, clientInfo: ClientInfo) =>
        getClientData(clientInfo) map {
          clientData => (clientId, clientData)
      }
    }
  }
}

此代码错误,因为它返回 Iterable[Future[(Int, ClientData)]]

信息 getClients 是一种节俭方法,它返回 Future[Map[A, B]] 其中 Map 是可变的,因此我需要将其转换为不可变先用 toMap 映射。

提前感谢您的帮助!

【问题讨论】:

    标签: scala twitter map future finagle


    【解决方案1】:
    scala> def f: Future[Map[String, Future[Int]]] = ???
    f: Future[Map[String,Future[Int]]]
    
    scala> def x = for {
         |   m <- f
         |   i = m.map{ case (k, fv) => fv.map{ k -> _ } }
         |   l <- Future.sequence(i)
         | } yield l.toMap
    x: Future[Map[String,Int]]
    

    一步一步:

    将Future[Map[A, Future[B]]] 转换为Future[Iterable[Future[(A, B)]]]:

    scala> def x1 = f.map{ _.map{ case (k, fv) => fv.map{ k -> _ } } }
    x1: Future[Iterable[Future[(String, Int)]]]
    

    使用flatMap 将Iterable[Future[(A, B)]] 转换为Future[Iterable[(A, B)]] 和flatten Future[Future[...]]:

    scala> def x2 = x1.flatMap{ Future.sequence(_) }
    x2: Future[immutable.Iterable[(String, Int)]]
    

    将Iterable[(A, B)] 转换为Map[A, B]:

    scala> def x = x2.map{ _.toMap }
    x: Future[Map[String,Int]]
    

    对于com.twitter.util.Future,您应该在collect 之前使用collect 而不是sequence 和toSeq,因为它接受Seq:

    def x = for {
      m <- f
      i = m.map{ case (k, fv) => fv.map{ k -> _ } }
      l <- Future.collect(i.toSeq)
    } yield l.toMap
    

    【讨论】:

    • 非常感谢您的快速回复!但是 Finagle 中没有 Future.sequence!有一个 Future.collect 但它似乎在这里不起作用...
    • @user3063038: 你的 scala 版本是多少? Here is sequence method 在 2.10.3 中。
    • 我使用的是 2.10.3 但 com.twitter.util.Future 显然没有序列方法:twitter.github.io/util/util-core/target/doc/main/api/com/…
    • @user3063038:查看更新。 collect 应该可以正常工作(在toSeq 之后)。
    • 是的!同时我也试过了,效果很好!非常感谢!
    猜你喜欢
    • 2013-07-02
    • 2020-07-16
    • 1970-01-01
    • 1970-01-01
    • 2021-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-19
    相关资源
    最近更新 更多