如何基于键值使用Groovy将一个JSON的信息丰富到另一个JSON
Groovy实现JSON节点按ID匹配追加名称字段
需求
根据MainJson中各节点的id值,匹配SecondJson里code字段相同的条目,将对应的name对象追加到MainJson的对应节点中。
输入示例
MainJson
[ { "webshop": [ { "id": "1168190", "type": "segment", "values": [ { "id": "1168191", "type": "application", "values": [ { "id": "1168192", "type": "productRange" }, { "id": "1168193", "type": "productRange" } ] }, { "id": "1168194", "type": "application", "values": [ { "id": "1168195", "type": "productRange" }, { "id": "1168196", "type": "productRange" } ] } ] } ] }]
SecondJson
{ "ProductCategorization": [ { "code": "1168190", "name": [ { "en": "Irrigation" }, { "es": "Riego" } ] }, { "code": "1168191", "name": [ { "ES": "Kenadrain" }, { "EN": "Kenadrain" } ] }, { "code": "1168192", "name": [ { "ES": "Fluxol" }, { "EN": "Fluxol" } ] }, { "code": "1168193", "name": [ { "EN": "PP System Jimten" }, { "ES": "PP System Jimten" } ] }]}
期望输出
[ { "webshop": [ { "id": "1168190", "type": "segment", "name": [ { "en": "Irrigation" }, { "es": "Riego" } ], "values": [ { "id": "1168191", "type": "application", "name": [ { "ES": "Kenadrain" }, { "EN": "Kenadrain" } ], "values": [ { "id": "1168192", "type": "productRange", "name": [ { "ES": "Fluxol" }, { "EN": "Fluxol" } ] }, { "id": "1168193", "type": "productRange", "name": [ { "EN": "PP System Jimten" }, { "ES": "PP System Jimten" } ] } ] }, { "id": "1168194", "type": "application", "values": [ { "id": "1168195", "type": "productRange" }, { "id": "1168196", "type": "productRange" } ] } ] } ] }]
问题代码分析
你提供的代码存在几个关键问题:
- 循环变量混淆:多层
each循环中错误使用外层it.id,而非当前节点的id,导致匹配逻辑完全错误。 - 重复低效查找:每次匹配都调用
findAll遍历整个ProductCategorization列表,效率低下。 - 遍历层级错误:多层嵌套的
it.values.each逻辑混乱,未正确遍历所有层级节点。
修正后的代码
def json1 = message.getBody(String) def map = message.getHeaders() def json2 = map.get("category") def slurper = new JsonSlurper() def json1Obj = slurper.parseText(json1) def json2Obj = slurper.parseText(json2) // 构建code到name的映射表,避免重复遍历查找 def codeToNameMap = json2Obj.ProductCategorization.collectEntries { [(it.code): it.name] } // 递归遍历所有带id的节点,添加对应name def enrichNode(node) { if (node.id && codeToNameMap.containsKey(node.id)) { node.name = codeToNameMap[node.id] } // 递归处理子节点 if (node.values instanceof Collection) { node.values.each { enrichNode(it) } } } // 启动遍历 json1Obj.each { root -> root.webshop?.each { enrichNode(it) } } def out = JsonOutput.toJson(json1Obj) message.setBody(out) return message
代码说明
- 映射表优化:将SecondJson的
code作为键、name作为值存入Map,后续查找仅需O(1)时间,大幅提升效率。 - 递归遍历:通过
enrichNode函数递归处理所有层级节点,无论嵌套多深,只要节点有id且映射表存在对应值,就自动添加name字段。 - 逻辑清晰:避免了多层循环的变量混淆,确保每个节点都被正确匹配处理。
内容的提问来源于stack exchange,提问作者Kumar Badam
相关产品推荐
相关产品推荐

