2016-08-04 91 views
-1

我想轉換下面的scala代碼?轉換scala地圖字符串 - >字符串轉換爲字符串 - >地圖

val orig = Map("command.stamp" -> 5, "command.another" -> "0", "level1.level2.level3" -> 10) which would translate to 

發送地圖。新地圖需要支持多個值類型和兩個以上的水平

val newMap = Map("command" -> Map("stamp" -> 5, "another" -> "0"), "level1" -> Map("level2" -> Map("level3" -> 10))) 

此外,我必須把它轉換成JSON。一直使用Json.toJson(newMap),但它可能有多種類型。

回答

0

下,你總是有鑰匙圖案「one.two」假設這將工作:

val orig = Map("command.stamp" -> 5, "command.another" -> 0) 

newMap = orig.foldLeft(immutable.Map[String, Map[String, Int]]())((prev, elem) => { 
    val ar = elem._1.split('.') 
    prev.get(ar(0)) match { 
    case None => (prev + (ar(0) -> immutable.Map((ar(1), elem._2)))) 
    case Some(entry) => 
     prev + (ar(0) -> (immutable.Map((ar(1), elem._2)) ++ entry)) 
    } 
}) 

基本上蔭摺疊和傳播的輸出圖。第一種情況只是檢查,如果還沒有這個鍵的條目。否則,如果存在,值圖將被提取並顯式附加。 它不知道這是否是最好的解決方案。我想過使用zip和其他迭代方法的版本,但沒有。

+0

這工作,但我的使用情況是有點不同的,那麼我想 – richs

+0

@Mikel做相同的,但在一個更好的方式。告訴我你的用例如何不同或相應地編輯問題。也許這會有所幫助。 – sascha10000

+0

我編輯了問題 – richs

1

我會做這個

map.foldLeft(Map[String,Map[String,Int]]()) { 
    case (map, (k,v)) => 
     val keys = k.split('.') 
     map + ((keys(0), map.getOrElse(keys(0), Map[String,Int]()) + (keys(1) -> v))) 
    } 
0

讓我們假設一個testMap將用於演示目的另一個前綴組:

val testmap:Map[String,Int] = Map("command.stamp" -> 5, "command.another" -> 0, 
            "command2.stamp2" -> 4, "command2.another2" -> 1) 

我們可以先標記化 「」由前綴,其次是組分析各子地圖剝離前綴:

for { 
    (k,v) <- testmap.groupBy{ _._1.split("\\.")(0) } //first tokenize by "." and group by prefix 
    } yield (k -> v.map{case(subKey,subValue) => subKey.replace(k,"").replace("\\.","") -> subValue }) //stripping prefix from submaps 
3
scala> map.groupBy(_._1.split('.')(0)) 
      .mapValues(_ map { case(k, v) => (k.split('.')(1), v) }) 
res1: scala.collection.immutable.Map[String,scala.collection.immutable.Map[String,Int]] = 
      Map(command -> Map(stamp -> 5, another -> 0)) 
相關問題