2012-03-09 52 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)))