2017-02-21 39 views

ответ

2

Существует нет ничего встраивается в стандартные библиотеки для этого, но это достаточно легко реализовать, например,

def combineFutures[K,V](m: Map[K,Future[V]]): Future[Map[K,V]] = { 
    m.foldLeft(Future.successful(Map.empty[K, V])) { 
     case (futureAcc: Future[Map[K, V]], (k: K, futureV: Future[V])) => 
      for { 
       acc <- futureAcc 
       v <- futureV 
      } yield acc + (k -> v) 
    } 
} 

// Mutable HashMap version 
import scala.collection.mutable.HashMap 
def combineFutures[K,V](m: HashMap[K,Future[V]]): Future[HashMap[K,V]] = { 
    m.foldLeft(Future.successful(HashMap.empty[K, V])) { 
     case (futureAcc: Future[HashMap[K, V]], (k: K, futureV: Future[V])) => 
      for { 
       acc <- futureAcc 
       v <- futureV 
      } yield { 
       acc.put(k, v) 
       acc 
      } 
    } 
} 

(я добавил некоторые дополнительные аннотации ненужных типа выше для ясности.)

4

Не уверен, что о функции вне из коробки, но я сделаю это сам так:

import scala.collection.mutable.HashMap 
import scala.concurrent.Future 
import scala.concurrent.ExecutionContext.Implicits.global 

val a: HashMap[Int, Future[Int]] = HashMap((1, Future(42)), (2, Future(43))) 
val iterOfFutures = a.map { case (k, v) => v.map(vv => (k, vv)) } 
val futureMap: Future[Map[Int, Int]] = Future.sequence(iterOfFutures).map(_.toMap) 

futureMap.map(println) // Map(2 -> 43, 1 -> 42) 
Thread.sleep(100) 

EDIT:

Не главное вопроса, но если вы хотите использовать изменяемую HashMap вместо неизменяемой карты, вам необходимо ее преобразовать. Вот некрасиво-иш путь от верхней части моей головы, возможно, есть что-то лучше:

val futureMap: Future[HashMap[Int, Int]] = 
    Future.sequence(iterOfFutures).map(s => HashMap(s.toSeq: _*))