Как объединить две карты в одну с ключами от первой карты и объединенными значениями? - PullRequest
3 голосов
/ 10 марта 2012

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

Iterable[Map[String, Map[String,Float]]

Пример:

val map1 = Iterable(Map(
  1 -> Map(key1 -> val1), 
  2 -> Map(key2 -> val2), 
  3 -> Map(key3 -> val3)
))

val map2 = Iterable(Map(
  1 -> Map(key11 -> val11), 
  3 -> Map(key33 -> val33), 
  4 -> Map(key44 -> val44), 
  5 -> Map(key55 -> val55)
))

Я хочу, чтобы полученная карта была следующей:

Map(
  1 -> Map(key1 -> val1, key11 -> val11), 
  3 -> Map(key3 -> val3, key33 -> val33)
)

Ответы [ 3 ]

10 голосов
/ 10 марта 2012

Обновление: я не совсем понимаю, что означает ваша правка о Iterable s или ошибка в вашем комментарии, но вот полный рабочий пример с String s и Float s:

val map1: Map[Int, Map[String, Float]] = Map(
  1 -> Map("key1" -> 1.0F),
  2 -> Map("key2" -> 2.0F),
  3 -> Map("key3" -> 3.0F))

val map2: Map[Int, Map[String, Float]] = Map(
  1 -> Map("key11" -> 11.0F),
  3 -> Map("key33" -> 33.0F), 
  4 -> Map("key44" -> 44.0F),      
  5 -> Map("key55" -> 55.0F))

val map3: Map[Int, Map[String, Float]] = for {
  (k, v1) <- map1
  v2 <- map2.get(k)
} yield (k, v1 ++ v2)

Обновление в ответ на ваш вопрос ниже: не имеет большого смысла иметь список карт, каждая из которых содержит одно отображение.Вы можете очень легко объединить их в одну карту, используя reduceLeft:

val maps = List(
  Map(1216 -> Map("key1" -> 144.0F)),
  Map(1254 -> Map("key2" -> 144.0F)),
  Map(1359 -> Map("key3" -> 144.0F))
)

val bigMap = maps.reduceLeft(_ ++ _)

Теперь у вас есть одна большая карта целых чисел с картами строк и с плавающей точкой, которую вы можете включить в мой ответ выше.*

6 голосов
/ 10 марта 2012
val keys = map1.keySet & map2.keySet
val map3 = keys.map(k => k -> (map1(k) ++ map2(k)))
0 голосов
/ 14 февраля 2014

Я играл с чем-то похожим, чтобы преобразовать Seq(Map("one" -> 1), Map("two" -> 2)) в Map("one" -> 1, "two" -> 2).

Я смотрел на предыдущие ответы и думал, что это слишком сложно. Немного поиграв, я обнаружил, что это решение работает и его легко:

val seqOfMaps = Seq(Map("one" -> 1), Map("two" -> 2))
seqOfMaps: Seq[scala.collection.immutable.Map[String,Int]] = List(Map(one -> 1), Map(two -> 2))

val allInOneMap = seqOfMaps.flatten.toMap
allInOneMap: scala.collection.immutable.Map[String,Int] = Map(one -> 1, two -> 2)

Преимущество этого подхода в том, что возможные пустые карты автоматически отфильтровываются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...