如何将嵌套JSON解析为键用.分隔的Map[String,String]结构
嵌套JSON按点分隔键扁平化转Map实现
核心逻辑是递归遍历JSON结构,每深入一层对象就将当前键拼接到路径前缀后,遍历到叶子节点时,将拼接完成的全路径作为键、叶子节点值作为值存入结果Map。
可直接运行的实现(Scala 环境)
以下实现基于轻量JSON库ujson,核心递归逻辑可平移到任意JSON库:
import ujson._ def flattenNestedJson(jsonObj: Obj, pathPrefix: String = ""): Map[String, String] = { jsonObj.value.foldLeft(Map.empty[String, String]) { (res, entry) => val (currentKey, currentValue) = entry val fullPath = if pathPrefix.isBlank then currentKey else s"$pathPrefix.$currentKey" currentValue match case subObj: Obj => res ++ flattenNestedJson(subObj, fullPath) case leafValue => res + (fullPath -> leafValue.str) } } // 测试调用 val sourceJson = ujson.read(""" { "key-1":{ "sub-key-1-1":{ "sub-key-1-1-1":"value111" }, "sub-key-1-2":{ "sub-key-1-2-1":"value121" } }, "key-2":{ "sub-key-2-1":{ "sub-key-2-1-1":"value211" } } } """).obj val targetMap = flattenNestedJson(sourceJson)
运行后得到的targetMap和预期结果完全一致:
Map( "key-1.sub-key-1-1.sub-key-1-1-1" -> "value111", "key-1.sub-key-1-2.sub-key-1-2-1" -> "value121", "key-2.sub-key-2-1.sub-key-2-1-1" -> "value211" )
适配调整说明
- 如果JSON叶子节点存在数字、布尔、null等非字符串类型,将代码里的
leafValue.str替换为leafValue.toString即可兼容 - 如果业务场景包含数组类型节点,可额外增加数组匹配分支,按索引拼接路径(比如
list.0、list.1的格式)即可 - 如果项目已经引入Circe、Play-JSON、Jackson等其他JSON库,只需要替换对应JSON对象、值的类型判断逻辑,递归拼接路径的核心逻辑不需要改动。
内容的提问来源于stack exchange,提问作者gianglaodai
相关产品推荐
相关产品推荐

