将地图列表转换为scala中的单个地图

时间:2012-03-09 22:28:07

标签: scala

  

可能重复:
  Scala How to create a new map from two other maps

我有以下需要转换为单个地图的地图列表。这样做的最佳方式是什么?

地图列表的类型为:

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

示例:

val list1 = List(Map(1216 -> Map(key1 -> 144.0)), 
     Map(1253 -> Map(key1 -> 144.0)), 
     Map(1359 -> Map(key1 -> 144.0))

val list2 = List(Map(1216 -> Map(key2 -> 148.0)), 
     Map(1200 -> Map(key2 -> 144.0)), 
     Map(1359 -> Map(key2 -> 144.0))

我想要一个结果地图

val map3 = Map(
        1216 -> Map(key1 -> 1440, key2 -> 148.0), 
        1359 -> Map(key1 -> 1440, key2 -> 144.0))

感谢

2 个答案:

答案 0 :(得分:0)

首先,查找新地图中应该包含的所有密钥,这两个密钥都存在于两个地图列表中(我假设):

val keys = list1.map(_.keySet).reduceLeft(_ | _) & list2.map(_.keySet).reduceLeft(_ | _)

然后选出所有这些键的值:

val alllist = list1 ++ list2
val map3 = keys.map(k => k -> alllist.flatMap(_ get k).reduceLeft(_ ++ _))

不是超级高效,但它完成了工作。

答案 1 :(得分:0)

如果我做对了,这样的事情就可以解决问题:

scala> import scalaz._
import scalaz._

scala> import Scalaz._
import Scalaz._

scala> list1 ++ list2
res2: List[scala.collection.immutable.Map[Int,scala.collection.immutable.Map[java.lang.String,Double]]] = List(Map(1216 -> Map(key1 -> 144.0)), Map(1253 -> Map(key1 -> 144.0)), Map(1359 -> Map(key1 -> 144.0)), Map(1216 -> Map(key2 -> 148.0)), Map(1200 -> Map(key2 -> 144.0)), Map(1359 -> Map(key2 -> 144.0)))


scala> .foldLeft(Map[Int,Seq[Map[String,Double]]]()) { case (acc, v) => 
     | v.mapValues(Seq(_)) |+| acc
     | }
res8: scala.collection.immutable.Map[Int,Seq[Map[String,Double]]] = Map(1216 -> List(Map(key2 -> 148.0), Map(key1 -> 144.0)), 1253 -> List(Map(key1 -> 144.0)), 1359 -> List(Map(key2 -> 144.0), Map(key1 -> 144.0)), 1200 -> List(Map(key2 -> 144.0)))


scala> .map { case(i, m) => (i, m reduce (_ ++ _)) }
res11: scala.collection.immutable.Map[Int,Map[String,Double]] = Map(1216 -> Map(key2 -> 148.0, key1 -> 144.0), 1253 -> Map(key1 -> 144.0), 1359 -> Map(key2 -> 144.0, key1 -> 144.0), 1200 -> Map(key2 -> 144.0))y2 -> 148.0)), Map(1200 -> Map(key2 -> 144.0)), Map(1359 -> Map(key2 -> 144.0)))