如何使用DataWeave根据订单数量条件缩减数组Payload?
需求说明
我有如下JSON库存数据:
[ { "Id": "6812", "status": "Available", "expirationDate": "2024-04-30T13:00:00.000-07:00", "quantityOnHand": 6124 }, { "Id": "7491", "status": "Available", "expirationDate": "2024-06-29T13:00:00.000-07:00", "quantityOnHand": 864 }, { "NetsuiteId": "6569", "status": "Available", "expirationDate": "2100-12-12T13:00:00.000-07:00", "quantityOnHand": 3 }, { "Id": "6582", "status": "Available", "expirationDate": "2100-12-12T13:00:00.000-07:00", "quantityOnHand": 1 } ]
通过变量vars.quantityOrder设置订单数量,需要返回足够满足该订单数量的库存项(按原顺序取,直到累计库存≥订单量),示例如下:
- 当
vars.quantityOrder = 100时,返回第一个项:
{ "Id": "6812", "status": "Available", "expirationDate": "2024-04-30T13:00:00.000-07:00", "quantityOnHand": 6124 }
- 当
vars.quantityOrder = 6500时,返回前两个项(累计6124+864=6988≥6500):
[ { "Id": "6812", "status": "Available", "expirationDate": "2024-04-30T13:00:00.000-07:00", "quantityOnHand": 6124 }, { "Id": "7491", "status": "Available", "expirationDate": "2024-06-29T13:00:00.000-07:00", "quantityOnHand": 864 } ]
我是DataWeave新手,写了以下代码但有语法逻辑问题,请求指导:
%dw 2.0 output application/json var quantityOrder = vars.quantityOrder var result = payload filter ((item, index) -> quantityOrder > 0) map ((item, index) -> { "Id": item.Id, "status": item.status, "expirationDate": item.expirationDate, "quantity": item.quantityOnHand - quantityOrder }) --- result
正确实现代码
%dw 2.0 output application/json var quantityOrder = vars.quantityOrder as Number // 确保订单量为数字类型 // 通过reduce累计库存,收集满足需求的项 var selectedItems = payload reduce ((item, acc={total: 0, items: []}) -> if (acc.total >= quantityOrder) acc else { total: acc.total + (item.quantityOnHand default 0), items: acc.items << item } ).items // 匹配示例格式:单元素时返回对象,多元素返回数组 --- if (sizeOf(selectedItems) == 1) selectedItems[0] else selectedItems
代码逻辑解释
- 类型校验:将
vars.quantityOrder转为Number类型,避免非数字值导致的计算异常。 - 累计筛选:
- 初始化累加器
acc,包含total(累计库存总量)和items(已选库存项数组)两个字段。 - 遍历每个库存项:若累计库存已满足订单量,直接返回当前累加器;否则将当前项加入已选数组,并更新累计库存。
- 初始化累加器
- 格式适配:如果最终只选中一个项,返回单个对象(和示例格式一致),否则返回数组。
额外优化提示
如果需要统一库存项的ID字段(比如把第三个项的NetsuiteId转为Id),可以修改reduce中的items赋值逻辑:
items: acc.items << item update { case .Id -> item.NetsuiteId default item.Id }
内容的提问来源于stack exchange,提问作者Arabian
相关产品推荐
相关产品推荐

