Scala: список будущего карты - PullRequest
1 голос
/ 26 апреля 2020

У меня есть список, который содержит Future of Map

val m1 = Future(Map(("A" -> 1), ("B" -> 1)))

val m2 = Future(Map(("A" -> 1), ("C" -> 1)))

val m3 = Future(Map(("C" -> 5), ("D" -> 1)))

val list = List(m1, m2, m3)

Я хочу объединить все карты и агрегировать значение ключа. Я хочу вывод, как показано ниже

Future(Map(A -> 2, B -> 1, C -> 6, D -> 1)

Как я могу выполнить то же самое.

Ответы [ 2 ]

3 голосов
/ 26 апреля 2020

Вы можете использовать метод Future.sequence, чтобы выполнить преобразование из List[Future[Map[_, _]]] в Future[List[Map[_, _]]], а затем объединить карты, используя функцию Reduce в списке, и передать ей свою собственную функцию объединения.

Пример:

val list = List(m1, m2, m3)

def merge(first: Map[String, Int], second: Map[String, Int]): Map[String, Int] = {
  first ++ second.map { case (k, v) => (k, v + first.getOrElse(k, 0)) }
}

Future.sequence(list).map(_.reduce(merge _)) // will produce Future(Map(A -> 2, B -> 1, C -> 6, D -> 1))
1 голос
/ 27 апреля 2020

Я бы сделал что-то вроде этого:

val m1 = Future(Map(("A" -> 1), ("B" -> 1)))
val m2 = Future(Map(("A" -> 1), ("C" -> 1)))
val m3 = Future(Map(("C" -> 5), ("D" -> 1)))

val futures = List(m1, m2, m3) 
val future = Future.sequence(futures) // Converts List of Future to Future of List
val futureMap = future.map(_.flatMap(_.toList).toMap)

В основном это преобразует Seq[Map[String, Int]] в первое Seq[(String, Int)], а затем, наконец, преобразует его в Map: Map[String, Int].

...