1

次の問題を修正しようとしています。

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 を使用して不変のマップに変換する必要があります。

よろしくお願いします。

4

1 に答える 1

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

に変換Iterable[Future[(A, B)]]Future[Iterable[(A, B)]]flatten Future[Future[...]]使用するflatMap:

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必要があります:collectsequencetoSeqcollectSeq

def x = for {
  m <- f
  i = m.map{ case (k, fv) => fv.map{ k -> _ } }
  l <- Future.collect(i.toSeq)
} yield l.toMap
于 2013-12-03T20:23:15.953 に答える