Groovy结合findAll、unique实现JSON数组条件去重,优先保留含Misc字段记录
现有Groovy去重写法的问题排查与正确实现
现有写法的核心问题
- 无参
unique()存在逻辑局限:无参调用时是对元素做全字段全等比对,既没有按照业务要求的「Name+Age一致」作为去重判定维度,也没有配套的优先级规则;后续接的findAll逻辑里引用了未正确关联的site变量,判断条件完全和业务需求脱节。 - 自定义
unique闭包存在逻辑偏差:传入unique的闭包如果只按Misc字段做对比,相当于把去重的判断维度从「同Name+Age的条目」换成了「按Misc排序去重」,从根本上偏离了业务的分组规则,无法实现“同Name/Age下优先保留带Misc字段条目”的效果。
符合需求的实现思路
核心逻辑拆分两步:
- 先把所有动物条目按照
Name + Age的组合值做分组,把同名称、同年龄的条目归到同一个组里 - 遍历每个分组,组内优先筛选带有非空
Misc字段的条目;如果组内所有条目都没有Misc字段,就正常保留原有条目
具体实现代码
基础版本可直接适配你的示例场景:
parsedJson.Animals = parsedJson.Animals // 按Name+Age组合值生成分组key .groupBy { "${it.Name}_${it.Age}" } .collect { groupKey, groupItems -> // 同组内优先查找带有效Misc的条目,找不到就取组内第一个元素 groupItems.find { it.Misc?.trim() } ?: groupItems.first() }
如果需要适配空对象、空字段的异常场景,可以使用带空值防护的健壮版本:
parsedJson.Animals = parsedJson.Animals ?.groupBy { "${it?.Name?.trim() ?: ''}_${it?.Age ?: ''}" } ?.collect { groupKey, groupItems -> groupItems.find { it?.Misc?.trim() } ?: groupItems?.first() }
上述实现运行后,最终输出的Animals数组会和你预期的结构完全一致:保留独立的monkey条目,两个同Name同Age的lion条目里优先留下带Misc字段的那条。
内容的提问来源于stack exchange,提问作者Kim
相关产品推荐
相关产品推荐

