PlayFramework:在Scala/Play中实现扁平JSON到嵌套JSON的转换
在Scala/Play中转换扁平带点键的JSON为嵌套结构
嗨,这个需求我之前在项目里碰到过,其实用Play框架自带的JSON API就能轻松搞定,给你两种实用的实现方式:
方法一:利用Play的JsPath自动创建嵌套结构
这种方法最简洁,Play的JsPath API会帮我们自动处理嵌套层级的创建,不用自己写递归逻辑:
首先确保你导入了Play JSON的核心包:
import play.api.libs.json._
然后处理你的JSON:
// 原始JSON字符串 val originalJsonStr = """{ "value.first" : "one", "value.second" : "two", "value.third" : "three" }""" // 解析成JsObject val originalJson = Json.parse(originalJsonStr).as[JsObject] // 转换逻辑 val transformedJson = originalJson.fields.foldLeft(JsObject.empty) { case (acc, (key, value)) => // 将带点的键拆分成路径段,构建JsPath val path = key.split('.').foldLeft(JsPath: JsPath)(_ \ _) // 把值设置到对应路径上,自动创建嵌套结构 path.json.set(value)(acc).getOrElse(acc) } // 输出结果:{"value":{"first":"one","second":"two","third":"three"}} println(Json.prettyPrint(transformedJson))
原理很简单:遍历原始JSON的每个键值对,把带.的键拆分成路径(比如value.first变成JsPath \ "value" \ "first"),然后用path.json.set把值插入到空对象的对应路径中——Play会自动帮我们创建缺失的嵌套层级,最后合并所有结果就得到了想要的结构。
方法二:手动递归构建嵌套对象
如果你想更清晰地控制嵌套逻辑,可以写一个递归函数来构建嵌套的JsObject:
import play.api.libs.json._ // 递归构建单个键对应的嵌套对象 def buildNested(keys: List[String], value: JsValue): JsObject = keys match { case last :: Nil => Json.obj(last -> value) case head :: tail => Json.obj(head -> buildNested(tail, value)) case Nil => JsObject.empty } // 遍历所有键值对,合并嵌套对象 def flattenToNested(obj: JsObject): JsObject = { obj.fields.foldLeft(JsObject.empty) { case (acc, (key, value)) => val keyParts = key.split('.').toList acc.deepMerge(buildNested(keyParts, value)) } } // 使用示例 val originalJson = Json.parse("""{ "value.first" : "one", "value.second" : "two", "value.third" : "three" }""").as[JsObject] val transformedJson = flattenToNested(originalJson)
这个方法通过递归把每个带点的键拆分成层级列表,然后一层一层构建嵌套对象,最后用deepMerge把所有小的嵌套对象合并成完整的JSON。
两种方法都能完美解决你的问题,第一种更简洁,推荐日常使用;第二种适合需要自定义嵌套逻辑的场景。
内容的提问来源于stack exchange,提问作者soumayaKoch
相关产品推荐
相关产品推荐

