2015-11-02 80 views
1

作爲練習和一些內部UTIL我建,我想採用Java屬性文件轉換成JSON層次轉換Java屬性映射到嵌套地圖JSON

foo.bar=15 
foo.lots.dir=/tmp/test 
foo.baz.host=localhost 
foo.baz.port=333 

我已經成功地轉換爲Scala的地圖,這裏是代碼:

import java.util._ 
import scala.io._ 
import scala.collection.JavaConverters._ 
import java.io._ 

val props : Properties = new Properties(); 

在REPL,你

scala> props.asScala 
res3: scala.collection.mutable.Map[String,String] = Map(foo.bar -> 15, foo.lots.dir -> /tmp/test, foo.baz.host -> localhost, foo.baz.port -> 333) 

問題現在變成了,我怎麼遍歷這個地圖和摺疊點符號嵌套地圖:

Map(
    foo -> Map(
     bar -> 15, 
     baz -> Map(
      port -> 333, 
      host -> localhost 
     ) 
    ) 
) 

也許使用Scala的遞歸? ;-)

這將饋入JSON構建器並將其轉換爲JSON格式。 (其中代碼我將在這裏發佈爲編輯,一旦我找出如何做上述嵌套地圖)

回答

0

甚至不要嘗試嵌套地圖。事情是,你會得到巨大的類型糾結,試圖區分對象,數組,葉節點等。你最終會創建自己的抽象語法樹(AST)。

只需遍歷地圖上的現有節點並直接創建JSON AST即可。 I like the one on json4s a lot。另外,JSON庫中有很多方法可以讓您的生活更輕鬆。

0

這似乎並非如此簡單的任務描述:) 但使用scala +函數式方法+遞歸 - 可以實現。 檢查下面的代碼。

val map = Map("foo.bar" -> "15", "foo.lots.dir" -> "/tmp/test", "foo.baz.host" -> "localhost", "foo.baz.port" -> "333") 


    def grouping(m: Map[List[String], Any]) : Map[List[String], Any] = { 
    println(m) 
    val rr = m.filter(_._1.nonEmpty).groupBy(_._1.head).map { el => 
     val internalMap = el._2.map(eel => eel._1.tail -> eel._2) 
     internalMap.size match { 
     case 1 => el._1 -> internalMap.head._2 
     case other => el._1 -> grouping(internalMap) 
     } 
    } 
    rr.map(el => List(el._1) -> el._2) 
    } 

    println(
    grouping(map.map(e => e._1.split("\\.").toList -> e._2)) 
) 

我的結果是:

Map(
    List(foo) -> Map(
     List(baz) -> Map(
      List(host) -> localhost, 
      List(port) -> 333 
      ), 
     List(lots) -> /tmp/test, 
     List(bar) -> 15 
    ) 
) 

從科學的觀點很有意思實施。但老實說,我沒有看到任何真正的應用。 最好創建Tree,其中每個節點用case class(name, child or value)來描述。