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

Ansible合并JSON对象时避免重复字段值叠加的方法

Ansible合并JSON对象时避免字符串字段拼接,保留单一值并合并数组

问题场景

合并两个结构相似的JSON对象时,data数组能正常合并,但month、year这类字符串字段会被错误拼接(比如值为"1"和"1"的month字段会变成"11"),需要保留这类字段的单一值,同时正常合并数组。

输入JSON1

{
    "data": [
        {
            "item_value_01": "APPLICATION",
            "quantity": 1
        },
        {
            "item_value_01": "HERBERT",
            "quantity": 1
        }
    ],
    "month": "1",
    "year": "2023"
}

输入JSON2

{
    "data": [
        {
            "item_value_01": "Test",
            "quantity": 1
        },
        {
            "item_value_01": "Country",
            "quantity": 1
        }
    ],
    "month": "1",
    "year": "2023"
}

当前错误输出

{
    "data": [
        {
            "item_value_01": "APPLICATION",
            "quantity": 1
        },
        {
            "item_value_01": "HERBERT",
            "quantity": 1
        },
        {
            "item_value_01": "Test",
            "quantity": 1
        },
        {
            "item_value_01": "Country",
            "quantity": 1
        }
    ],
    "month": "11",
    "year": "20232023"
}

期望输出

{
    "data": [
        {
            "item_value_01": "APPLICATION",
            "quantity": 1
        },
        {
            "item_value_01": "HERBERT",
            "quantity": 1
        },
        {
            "item_value_01": "Test",
            "quantity": 1
        },
        {
            "item_value_01": "Country",
            "quantity": 1
        }
    ],
    "month": "1",
    "year": "2023"
}

问题原因

原playbook对所有字段统一使用+运算符处理:

- set_fact:
    list: "{{ list|default({})| 
                combine({item: input1[item]|default([]) +
                               input2[item]|default([])}, recursive=true) }}"
  loop: "{{ (input2.keys()|list + input1.keys()|list)|unique }}"

+运算符处理数组时是合并操作,但处理字符串时会执行拼接,这就导致month、year这类字符串字段被错误拼接。

解决方案

通过判断字段类型,对数组和非数组字段分别处理:数组字段执行合并,非数组字段保留单一值(优先取第一个JSON的字段值,若不存在则取第二个的)。

修改后的playbook:

- set_fact:
    merged_result: "{{ merged_result|default({})|combine({
        item: (input1[item]|default([]) + input2[item]|default([])) 
              if (input1[item] is iterable and input1[item] is not string) 
              else input1[item]|default(input2[item])
    }, recursive=true) }}"
  loop: "{{ (input1.keys()|list + input2.keys()|list)|unique }}"

代码解释

  • input1[item] is iterable and input1[item] is not string:判断当前字段是否为数组(排除字符串类型,因为字符串本身也是可迭代对象)
  • 数组类型字段:执行+操作数组合并
  • 非数组类型字段:优先使用input1中的值,若input1没有该字段则使用input2的值(由于场景中两个JSON的对应字段值相同,最终结果一致)

运行该playbook后,即可得到符合预期的合并结果:data数组合并完整,month和year字段保留单一正确值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 07:15:31