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.
You can do this pretty concisely with Play's JSON transformers. The following is off the top of my head, and I'm sure it could be greatly improved on:
import play.api.libs.json._
val flattenMeta = (__ \ 'metadata).read[JsObject].flatMap(
_.fields.foldLeft((__ \ 'metadata).json.prune) {
case (acc, (k, v)) => acc andThen __.json.update(
Reads.of[JsObject].map(_ + (s"metadata.$k" -> v))
)
}
)
And then:
val json = Json.parse("""
{
"metadata": {
"id": "1234",
"type": "file",
"length": 395
}
}
""")
And:
scala> json.transform(flattenMeta).foreach(Json.prettyPrint _ andThen println)
{
"metadata.id" : "1234",
"metadata.type" : "file",
"metadata.length" : 395
}
Just change the path if you want to handle metadata
fields somewhere else in the tree.
Note that using a transformer may be overkill here—see e.g. Pascal Voitot's input in this thread, where he proposes the following:
(json \ "metadata").as[JsObject].fields.foldLeft(Json.obj()) {
case (acc, (k, v)) => acc + (s"metadata.$k" -> v)
}
It's not as composable, and you'd probably not want to use as
in real code, but it may be all you need.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With