2012-03-09 57 views
2

可能重复:
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)) 

感谢

回答

0

首先,找到所有sh的键乌尔德在你的新地图,这是存在于两个您的地图列表键(我假设):

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(_ ++ _)) 

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

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)))