Преобразование свойств 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();
В ответ вы получаете
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. (Какой код я опубликую здесь, как редактировать, как только я пойму, как сделать вышеупомянутую вложенную карту)
2 ответа
Это кажется не такой простой задачей, как описано:) Но используя 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)
,
Даже не пытайтесь использовать вложенную карту. Дело в том, что вы будете сильно запутываться с типами, пытаясь различить объекты, массивы, листовые узлы и т. Д. В итоге вы создадите свое собственное абстрактное синтаксическое дерево (AST).
Просто переберите существующие узлы на вашей карте и создайте JSON AST напрямую. Мне очень нравится тот, что на json4s. Кроме того, в библиотеках JSON есть множество методов, облегчающих вашу жизнь.