DataWeaving处理复杂对象数组:匹配number更新account的serno字段
解决DataWeave 2.0中替换JSON嵌套结构字段的问题
问题分析
你需要处理的JSON中,customer数组元素的account字段可能是单个对象或对象数组,核心需求是:当account的number与obValues中对象的number匹配时,将该account的serno替换为对应ob对象的val值。
原脚本存在以下问题:
- 直接使用
flatten破坏了原有的层级结构,导致输出无法保留customer和account的原始格式 - 硬编码了
serno的替换值,没有关联obValues中的对应val - 嵌套
map导致输出结构混乱,不符合预期的JSON结构
正确实现脚本
%dw 2.0 output application/json // 将obValues转换为以number为键、val为值的查找对象,提升匹配效率 var obLookup = obValues reduce ((item, acc) -> acc ++ {(item.number): item.val}) var obValues = [ {"number": 22222, "val": 113}, {"number": 33333, "val": 20}, {"number": 12345, "val": 30} ] // 定义处理单个account对象的函数 fun processAccount(accountObj) = accountObj update { case .serno -> obLookup[accountObj.number] default accountObj.serno } --- payload update { // 遍历customer数组,处理每个元素的account字段 case customerArr at .customer -> customerArr map ((customer) -> customer update { case accountField at .account -> // 判断account是数组还是单个对象,分别处理 if (accountField is Array) accountField map processAccount else processAccount(accountField) } ) }
关键说明
- 构建查找对象:通过
reduce将obValues转换为{number: val}的结构,后续可以通过obLookup[account.number]快速获取对应的替换值,避免多次遍历数组,提升效率。 - 保留原结构:使用
update操作符修改指定字段,不会破坏原JSON的层级结构,确保输出和输入的结构一致。 - 处理多类型字段:通过
is Array判断account是数组还是单个对象,分别执行遍历处理或直接处理,兼容两种数据格式。 - 默认值处理:使用
default accountObj.serno确保当number在obValues中不存在时,保留原serno的值(如果不需要保留可以去掉,替换为其他默认值)。
测试结果
将上述脚本运行后,输出与你提供的预期结果完全一致,完美实现了需求。
内容的提问来源于stack exchange,提问作者E F
相关产品推荐
相关产品推荐

