播放[Scala]:如何展平JSON对象 [英] Play [Scala]: How to flatten a JSON object
问题描述
给出以下JSON ...
Given the following JSON...
{
"metadata": {
"id": "1234",
"type": "file",
"length": 395
}
}
...如何将其转换为
... how do I convert it to
{
"metadata.id": "1234",
"metadata.type": "file",
"metadata.length": 395
}
Tx.
推荐答案
这绝对不是小菜一碟,但是可以通过尝试将其递归展平来实现.我还没有对它进行彻底的测试,但是它可以与您的示例以及我使用数组提出的其他一些基本示例一起使用:
This is definitely not trivial, but possible by trying to flatten it recursively. I haven't tested this thoroughly, but it works with your example and some other basic one's I've come up with using arrays:
object JsFlattener {
def apply(js: JsValue): JsValue = flatten(js).foldLeft(JsObject(Nil))(_++_.as[JsObject])
def flatten(js: JsValue, prefix: String = ""): Seq[JsValue] = {
js.as[JsObject].fieldSet.toSeq.flatMap{ case (key, values) =>
values match {
case JsBoolean(x) => Seq(Json.obj(concat(prefix, key) -> x))
case JsNumber(x) => Seq(Json.obj(concat(prefix, key) -> x))
case JsString(x) => Seq(Json.obj(concat(prefix, key) -> x))
case JsArray(seq) => seq.zipWithIndex.flatMap{ case (x, i) => flatten(x, concat(prefix, key + s"[$i]")) }
case x: JsObject => flatten(x, concat(prefix, key))
case _ => Seq(Json.obj(concat(prefix, key) -> JsNull))
}
}
}
def concat(prefix: String, key: String): String = if(prefix.nonEmpty) s"$prefix.$key" else key
}
JsObject
具有fieldSet
方法,该方法返回我映射的Set[(String, JsValue)]
,并与JsValue
子类匹配,并从那里继续递归使用.
JsObject
has the fieldSet
method that returns a Set[(String, JsValue)]
, which I mapped, matched against the JsValue
subclass, and continued consuming recursively from there.
您可以通过将JsValue
传递给apply
来使用此示例:
You can use this example by passing a JsValue
to apply
:
val json = Json.parse("""
{
"metadata": {
"id": "1234",
"type": "file",
"length": 395
}
}
"""
JsFlattener(json)
我们将其留给读者练习,以使代码看起来更漂亮.
这篇关于播放[Scala]:如何展平JSON对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!