1
    "ansible_facts": {
        "list1": [
            "10",
            "2",
            "4",
            "5",
            "6",
            "7",
            "7",
            "8",
            "9"
        ],
        "list2": [
            [
                "10",
                "xxxxx"
            ],
            [
                "2",
                "yyyyy"
            ],
            [
                "4",
                "zzzzz"
            ],
            [
                "5",
                "mmmmm"
            ],
            [
                "6",
                "fffff"
            ],
            [
                "7",
                "gggggg"
            ],
            [
                "8",
                "hhhhh"
            ],
            [
                "9",
                "kkkkkk"
            ]

Here I have two lists, I want to merge list2, just the words(xxxx,yyyy,...) with list1, but with condition that whenever the number on list2 match list1 then merge it to it's according number on list 1. But as you can see there can be some repeating number making it not perfectly aligned. When I sort the list like above still the the condition won't work when numbers repeat.

``
the condition that i've tried
    when: list1[item|int] == list2[item|int]
    with_sequence: start=0 end={{countvar.stdout|int - 1}}

Expected merged list
```

    "list3": [
        [
            "10",
            "xxxxx"
        ],
        [
            "2",
            "yyyyy"
        ],
        [
            "4",
            "zzzzz"
        ],
        [
            "5",
            "mmmmm"
        ],
        [
            "6",
            "fffff"
        ],
        [
            "7",
            "gggggg"
        ],
        [
            "7",
            "gggggg"
        ],
        [
            "8",
            "hhhhh"
        ],
        [
            "9",
            "kkkkkk"
        ]
GenZ
  • 49
  • 4

1 Answers1

2
Given the lists
  l1: ['10', '2', '4', '5', '6', '7', '7', '8', '9']
  l2:
    - ['10', xxxxx]
    - ['2', yyyyy]
    - ['4', zzzzz]
    - ['5', mmmmm]
    - ['6', fffff]
    - ['7', gggggg]
    - ['8', hhhhh]
    - ['9', kkkkkk]

  1. Convert the second list to a dictionary
  d2: "{{ dict(l2) }}"

gives

  d2:
    '10': xxxxx
    '2': yyyyy
    '4': zzzzz
    '5': mmmmm
    '6': fffff
    '7': gggggg
    '8': hhhhh
    '9': kkkkkk
  1. Extract the values
  v1: "{{ l1|map('extract', d2)|list }}"

gives

  v1: [xxxxx, yyyyy, zzzzz, mmmmm, fffff, gggggg, gggggg, hhhhh, kkkkkk]
  1. zip the lists
  l3: "{{ l1|zip(v1) }}"

gives what you're looking for

  l3:
    - ['10', xxxxx]
    - ['2', yyyyy]
    - ['4', zzzzz]
    - ['5', mmmmm]
    - ['6', fffff]
    - ['7', gggggg]
    - ['7', gggggg]
    - ['8', hhhhh]
    - ['9', kkkkkk]

You can put it in one line which gives the same result

  l3: "{{ l1|zip(l1|map('extract', dict(l2))|list) }}"

  • Example of a complete playbook for testing
- hosts: localhost

  vars:

    l1: ['10', '2', '4', '5', '6', '7', '7', '8', '9']
    l2:
      - ['10', xxxxx]
      - ['2', yyyyy]
      - ['4', zzzzz]
      - ['5', mmmmm]
      - ['6', fffff]
      - ['7', gggggg]
      - ['8', hhhhh]
      - ['9', kkkkkk]

    d2: "{{ dict(l2) }}"
    v1: "{{ l1|map('extract', d2)|list }}"
    l3: "{{ l1|zip(v1) }}"
    l4: "{{ l1|zip(l1|map('extract', dict(l2))|list) }}"

  tasks:

    - debug:
        var: d2
    - debug:
        var: v1|to_yaml
    - debug:
        var: l3|to_yaml
    - debug:
        var: l4|to_yaml
  • The filter to_yaml can use anchor
 l3|to_yaml: |-
    - ['10', xxxxx]
    - ['2', yyyyy]
    - ['4', zzzzz]
    - ['5', mmmmm]
    - ['6', fffff]
    - &id001 ['7', gggggg]
    - *id001
    - ['8', hhhhh]
    - ['9', kkkkkk]
shell> ansible-config dump | grep DEFAULT_STDOUT_CALLBACK
DEFAULT_STDOUT_CALLBACK(/scratch/test-061/ansible.cfg) = yaml
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63