Scala 将 Map[A, Seq[Future[Option[B]]]] 转换为 Future[Map[A, Seq[B]]]?
Scala convert Map[A, Seq[Future[Option[B]]]] to Future[Map[A, Seq[B]]]?
我被卡住了,想知道如何将 Map[A, Seq[Future[Option[B]]]]
转换为 Future[Map[A, Seq[B]]]
?
最简单的方法是:
val yourMap: Map[A, Seq[Future[Option[B]]]] = ...
val flattenedValues: Map[A, Future[Seq[B]]] = yourMap.mapValues { seqFuture =>
Future.sequence(seqFuture).map(seqOpt => seqOpt.flatten)
}
val seqOfFutures: Seq[Future[(A, Seq[B])]] = flattenedValues.toSeq.map {
case (a, futureSeqB) =>
future.map(optionB => a -> optionB)
}
val futureOfSeq: Future[Seq[(A, Seq[B])]] = Future.sequence(seqOfFutures)
val result: Future[Map[A, Seq[B]]] = futureOfSeq.map { seq =>
seq.groupBy(_._1).mapValues(_.map(_._2).flatten)
}
如果你定义了 2 个东西,你在问题版本 (Map[A, Future[Option[B]]
) 之前的内容将以更简单的方式处理猫
// as far as I can tell defined only in Alleycats
implicit def traverseMap[A]: cats.Traverse[Map[A, *]] = ...
// as far as I can tell defined in Cats
implicit def applicativeFuture: cats.Applicative[Future] = ...
那么你可以简单地做到这一点:
// assuming traverse syntax imported
val futureMap: Future[Map[A, Option[B]] = yourMap.sequence
然而,您当前表格中的数据迫使我们以艰难的方式进行。
此版本通过将 Map
转换为 List
然后再返回来避免重新分组数据。
val in: Map[A, Seq[Future[Option[B]]]] = ???
val out: Future[Map[A, Seq[B]]] =
Future.sequence(
in.toList.map {
case (k, v) => Future.sequence(v).map(k -> _.flatten)
}
).map(_.toMap)
内部map
使用Future.sequence
将每个条目从A -> Seq[Future[Option[B]]]
转换为Future[A -> Seq[B]]
。
外部Future.sequence
将List[Future[A -> Seq[B]]]
转换为Future[List[A -> Seq[B]]]
。
外部 map
将此 List
转换回 Map
。
这个编译所以类型是正确的,但我没有在任何真实数据上测试它
我被卡住了,想知道如何将 Map[A, Seq[Future[Option[B]]]]
转换为 Future[Map[A, Seq[B]]]
?
最简单的方法是:
val yourMap: Map[A, Seq[Future[Option[B]]]] = ...
val flattenedValues: Map[A, Future[Seq[B]]] = yourMap.mapValues { seqFuture =>
Future.sequence(seqFuture).map(seqOpt => seqOpt.flatten)
}
val seqOfFutures: Seq[Future[(A, Seq[B])]] = flattenedValues.toSeq.map {
case (a, futureSeqB) =>
future.map(optionB => a -> optionB)
}
val futureOfSeq: Future[Seq[(A, Seq[B])]] = Future.sequence(seqOfFutures)
val result: Future[Map[A, Seq[B]]] = futureOfSeq.map { seq =>
seq.groupBy(_._1).mapValues(_.map(_._2).flatten)
}
如果你定义了 2 个东西,你在问题版本 (Map[A, Future[Option[B]]
) 之前的内容将以更简单的方式处理猫
// as far as I can tell defined only in Alleycats
implicit def traverseMap[A]: cats.Traverse[Map[A, *]] = ...
// as far as I can tell defined in Cats
implicit def applicativeFuture: cats.Applicative[Future] = ...
那么你可以简单地做到这一点:
// assuming traverse syntax imported
val futureMap: Future[Map[A, Option[B]] = yourMap.sequence
然而,您当前表格中的数据迫使我们以艰难的方式进行。
此版本通过将 Map
转换为 List
然后再返回来避免重新分组数据。
val in: Map[A, Seq[Future[Option[B]]]] = ???
val out: Future[Map[A, Seq[B]]] =
Future.sequence(
in.toList.map {
case (k, v) => Future.sequence(v).map(k -> _.flatten)
}
).map(_.toMap)
内部map
使用Future.sequence
将每个条目从A -> Seq[Future[Option[B]]]
转换为Future[A -> Seq[B]]
。
外部Future.sequence
将List[Future[A -> Seq[B]]]
转换为Future[List[A -> Seq[B]]]
。
外部 map
将此 List
转换回 Map
。
这个编译所以类型是正确的,但我没有在任何真实数据上测试它