Search code examples
jsonansiblejinja2ansible-2.x

Merge 2 json arrays based on their keys


How can I merge 2 json arrays based on the same keys and add a 3rd item from the input json pog_id in the output json file? I have tried with the code mentioned below that is creating 2 different arrays inside a key in json and not merging the values inside a same array.

mergedobject.json

[
    {
        "name": "ALL_DMZ",
        "objectIds": [
            "29570",
            "29571"
        ],
        "orgid": "777777",
        "pog_id": "333333"
    },
    {
        "name": "ALL_DMZ",
        "objectIds": [
            "729548",
            "729549",
            "295568"
            
        ],
        "orgid": "777777",
        "pog_id": "333333"
    }
    
]

Playbook

- set_fact:
        output: "{{ output|d([]) + [{'orgid': item.0,
                                     'objectIds': item.1|
                                                  map(attribute='objectIds')|
                                                  list}] }}"
      loop: "{{ mergedobject|groupby('name') }}"

Current Output

[
    {
        "name": "ALL_DMZ",
        "objectIds": [
        [   "29570",
            "29571"
        ],
        [
            "729548",
            "729549",
            "295568"  
        ]
      ]
        "orgid": "777777"
    }
    
]

Expected Output

[
    {
        "name": "ALL_DMZ",
        "objectIds": [
            "29570",
            "29571",
            "729548",
            "729549",
            "295568"  
      ]
        "orgid": "777777",
        "pog_id": "333333"
    }
    
]

Solution

  • Given the data
      mergedobject:
        - name: ALL_DMZ
          objectIds: ['29570', '29571']
          orgid: '777777'
          pog_id: '333333'
        - name: ALL_DMZ
          objectIds: ['729548', '729549', '295568']
          orgid: '777777'
          pog_id: '333333'
    

    combine the items in the list. Append the lists in attributes

      output: "{{ mergedobject|combine(list_merge='append') }}"
    

    gives

      output:
        name: ALL_DMZ
        objectIds: ['29570', '29571', '729548', '729549', '295568']
        orgid: '777777'
        pog_id: '333333'
    

    You can put the result into a list

      output: "[{{ mergedobject|combine(list_merge='append') }}]"
    

    gives what you want

      output:
        - name: ALL_DMZ
          objectIds: ['29570', '29571', '729548', '729549', '295568']
          orgid: '777777'
          pog_id: '333333'