我如何将 HashMap[T,Future[N]] 转换为 Future[HashMap[T,N]]
how do i transform a HashMap[T,Future[N]] to Future[HashMap[T,N]]
我知道存在
Future.sequence
将 List[Future[T]]
转换为 Future[List[T]]
有什么方法可以将 HashMap[T,Future[N]]
转换为 Future[HashMap[T,N]]
吗?
不确定 out-of-the-box 函数,但我自己会这样做:
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)
编辑:
不是问题的重点,但是如果你想要一个可变的 HashMap 而不是不可变的 Map 那么你必须转换它。这是我想不到的 ugly-ish,也许还有更好的东西:
val futureMap: Future[HashMap[Int, Int]] =
Future.sequence(iterOfFutures).map(s => HashMap(s.toSeq: _*))
标准库中没有为此内置任何内容,但它很容易实现,例如
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
}
}
}
(为了清楚起见,我在上面添加了一些额外的不必要的类型注释。)
我知道存在
Future.sequence
将 List[Future[T]]
转换为 Future[List[T]]
有什么方法可以将 HashMap[T,Future[N]]
转换为 Future[HashMap[T,N]]
吗?
不确定 out-of-the-box 函数,但我自己会这样做:
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)
编辑:
不是问题的重点,但是如果你想要一个可变的 HashMap 而不是不可变的 Map 那么你必须转换它。这是我想不到的 ugly-ish,也许还有更好的东西:
val futureMap: Future[HashMap[Int, Int]] =
Future.sequence(iterOfFutures).map(s => HashMap(s.toSeq: _*))
标准库中没有为此内置任何内容,但它很容易实现,例如
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
}
}
}
(为了清楚起见,我在上面添加了一些额外的不必要的类型注释。)