You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用DataWeave动态展平嵌套JSON对象(适配多结构Payload)

DataWeave实现动态键适配的JSON笛卡尔积转换

需求说明

需要将输入JSON中Report_Entry条目下的非数组属性,与所有数组类型属性的元素进行笛卡尔积组合,生成平铺的对象数组。要求支持动态键适配——不管输入中数组类型的字段叫什么(比如示例中的Lines、Amendments),都能自动识别并参与笛卡尔积计算,无需硬编码字段名。

输入示例

{
  "Report_Entry": [
    {
      "Accepted_Currencies": "USD; EUR",
      "Amount": "22",
      "Lines": [{"Project": "Proj1"}, {"Project": "Proj2"}],
      "Amendments": [{"Name": "Amd 1", "Status": "Approved"}, {"Name": "Amd 2", "Status": "Approved"}]
    }
  ]
}

输出示例

[
  {"Accepted_Currencies": "USD; EUR", "Amount": "22", "Project": "Proj1", "Name": "Amd 1", "Status": "Approved"},
  {"Accepted_Currencies": "USD; EUR", "Amount": "22", "Project": "Proj1", "Name": "Amd 2", "Status": "Approved"},
  {"Accepted_Currencies": "USD; EUR", "Amount": "22", "Project": "Proj2", "Name": "Amd 1", "Status": "Approved"},
  {"Accepted_Currencies": "USD; EUR", "Amount": "22", "Project": "Proj2", "Name": "Amd 2", "Status": "Approved"}
]

解决方案(DataWeave 2.0)

完整转换代码

%dw 2.0
output application/json

// 递归实现任意数量数组的笛卡尔积
fun crossJoin(arrays: Object): Array<Object> =
    arrays match {
        // 终止条件:无数组时返回空对象数组
        case {} => [{}]
        // 递归拆分:取第一个数组,和剩余数组的笛卡尔积做flatMap组合
        case { first: var arr, rest: var remainingArrays } => 
            arr flatMap (item) -> 
                crossJoin(remainingArrays) map (crossItem) -> item ++ crossItem
    }
---
// 遍历每个Report_Entry条目
payload.Report_Entry flatMap (entry) ->
    do {
        // 1. 提取非数组类型的基础属性
        var baseProps = entry filterObject ((val, key) -> !isArray(val))
        // 2. 提取所有数组类型的字段值(保留元素原结构)
        var arrayCollections = entry filterObject ((val, key) -> isArray(val))
        // 3. 对所有数组做笛卡尔积
        var crossCombined = crossJoin(arrayCollections)
    }
    // 4. 每个笛卡尔积组合与基础属性合并,生成最终对象
    crossCombined map (combined) -> baseProps ++ combined

代码解释

  1. crossJoin递归函数:

    • 核心功能是处理任意数量的数组,生成它们的笛卡尔积组合。
    • 通过模式匹配拆分数组集合,递归计算剩余数组的笛卡尔积,再与当前数组的每个元素做扁平化组合。
  2. 主转换逻辑:

    • baseProps:筛选出当前Report_Entry中所有非数组的属性(比如示例里的Accepted_Currencies、Amount),作为每个结果对象的固定部分。
    • arrayCollections:筛选出所有数组类型的字段(比如Lines、Amendments),这些是需要做笛卡尔积的维度。
    • crossCombined:调用crossJoin得到所有数组元素的笛卡尔积组合。
    • 最后将每个组合与baseProps合并,得到平铺的结果对象。
  3. 动态适配特性:

    • 代码中没有硬编码任何数组字段名,完全通过isArray()判断识别数组字段。
    • 如果输入中新增其他数组字段(比如Items: [{"SKU": "A1"}, {"SKU": "A2"}]),代码会自动将其纳入笛卡尔积计算,无需修改逻辑。

内容的提问来源于stack exchange,提问作者Ayyappa P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 13:56:12