作为练习和一些内部工具的构建,我想将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 :(得分:0)
不要尝试嵌套地图。问题是,您将与类型纠缠在一起,尝试区分对象,数组,叶节点等。您最终将创建自己的抽象语法树(AST)。
只需迭代地图上的现有节点并直接创建JSON AST。 I like the one on json4s a lot。此外,JSON库中有很多方法可供您轻松使用。
答案 1 :(得分: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)