簡體   English   中英

如何將Twitter Future [Map [A​​,Future [C]]]轉換為Future [Map [A​​,C]]

[英]How to convert a Twitter Future[Map[A, Future[C]]] to a Future[Map[A, C]]

我正在嘗試解決以下問題:

我有一個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是一個節儉的方法,該方法返回Map是可變的Future [Map [A​​,B]] ,因此我需要先使用toMap將其轉換為不可變的地圖。

預先感謝您的幫助!

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

使用flatMapIterable[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而不是sequencetoSeq ,因為它接受Seq

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM