community.general.lists_mergeby filter – Merge two or more lists of dictionaries by a given attribute

Note

This filter plugin is part of the community.general collection (version 9.4.0).

It is not included in ansible-core. To check whether it is installed, run ansible-galaxy collection list.

To install it, use: ansible-galaxy collection install community.general.

To use it in a playbook, specify: community.general.lists_mergeby.

New in community.general 2.0.0

Synopsis

Input

This describes the input of the filter, the value before | community.general.lists_mergeby.

Parameter

Comments

Input

list / elements=any / required

A list of dictionaries, or a list of lists of dictionaries.

The required type of the elements is set to raw because all elements of _input can be either dictionaries or lists.

Positional parameters

This describes positional parameters of the filter. These are the values positional1, positional2 and so on in the following example: input | community.general.lists_mergeby(positional1, positional2, ...)

Parameter

Comments

another_list

list / elements=any

Another list of dictionaries, or a list of lists of dictionaries.

This parameter can be specified multiple times.

index

string / required

The dictionary key that must be present in every dictionary in every list that is used to merge the lists.

Keyword parameters

This describes keyword parameters of the filter. These are the values key1=value1, key2=value2 and so on in the following example: input | community.general.lists_mergeby(key1=value1, key2=value2, ...)

Parameter

Comments

list_merge

string

Modifies the behaviour when the dictionaries (hashes) to merge contain arrays/lists.

Choices:

  • "replace" ← (default)

  • "keep"

  • "append"

  • "prepend"

  • "append_rp"

  • "prepend_rp"

recursive

boolean

Should the combine recursively merge nested dictionaries (hashes).

Note: It does not depend on the value of the hash_behaviour setting in ansible.cfg.

Choices:

  • false ← (default)

  • true

Notes

Note

  • When keyword and positional parameters are used together, positional parameters must be listed before keyword parameters: input | community.general.lists_mergeby(positional1, positional2, key1=value1, key2=value2)

Examples

# Some results below are manually formatted for better readability. The
# dictionaries' keys will be sorted alphabetically in real output.

- name: Example 1. Merge two lists. The results r1 and r2 are the same.
  ansible.builtin.debug:
    msg: |
      r1: {{ r1 }}
      r2: {{ r2 }}
  vars:
    list1:
      - {index: a, value: 123}
      - {index: b, value: 4}
    list2:
      - {index: a, foo: bar}
      - {index: c, foo: baz}
    r1: "{{ list1 | community.general.lists_mergeby(list2, 'index') }}"
    r2: "{{ [list1, list2] | community.general.lists_mergeby('index') }}"

#  r1:
#    - {index: a, foo: bar, value: 123}
#    - {index: b, value: 4}
#    - {index: c, foo: baz}
#  r2:
#    - {index: a, foo: bar, value: 123}
#    - {index: b, value: 4}
#    - {index: c, foo: baz}

- name: Example 2. Merge three lists
  ansible.builtin.debug:
    var: r
  vars:
    list1:
      - {index: a, value: 123}
      - {index: b, value: 4}
    list2:
      - {index: a, foo: bar}
      - {index: c, foo: baz}
    list3:
      - {index: d, foo: qux}
    r: "{{ [list1, list2, list3] | community.general.lists_mergeby('index') }}"

#  r:
#    - {index: a, foo: bar, value: 123}
#    - {index: b, value: 4}
#    - {index: c, foo: baz}
#    - {index: d, foo: qux}

- name: Example 3. Merge single list. The result is the same as 2.
  ansible.builtin.debug:
    var: r
  vars:
    list1:
      - {index: a, value: 123}
      - {index: b, value: 4}
      - {index: a, foo: bar}
      - {index: c, foo: baz}
      - {index: d, foo: qux}
    r: "{{ [list1, []] | community.general.lists_mergeby('index') }}"

#  r:
#    - {index: a, foo: bar, value: 123}
#    - {index: b, value: 4}
#    - {index: c, foo: baz}
#    - {index: d, foo: qux}

- name: Example 4. Merge two lists. By default, replace nested lists.
  ansible.builtin.debug:
    var: r
  vars:
    list1:
      - {index: a, foo: [X1, X2]}
      - {index: b, foo: [X1, X2]}
    list2:
      - {index: a, foo: [Y1, Y2]}
      - {index: b, foo: [Y1, Y2]}
    r: "{{ [list1, list2] | community.general.lists_mergeby('index') }}"

#  r:
#    - {index: a, foo: [Y1, Y2]}
#    - {index: b, foo: [Y1, Y2]}

- name: Example 5. Merge two lists. Append nested lists.
  ansible.builtin.debug:
    var: r
  vars:
    list1:
      - {index: a, foo: [X1, X2]}
      - {index: b, foo: [X1, X2]}
    list2:
      - {index: a, foo: [Y1, Y2]}
      - {index: b, foo: [Y1, Y2]}
    r: "{{ [list1, list2] | community.general.lists_mergeby('index', list_merge='append') }}"

#  r:
#    - {index: a, foo: [X1, X2, Y1, Y2]}
#    - {index: b, foo: [X1, X2, Y1, Y2]}

- name: Example 6. Merge two lists. By default, do not merge nested dictionaries.
  ansible.builtin.debug:
    var: r
  vars:
    list1:
      - {index: a, foo: {x: 1, y: 2}}
      - {index: b, foo: [X1, X2]}
    list2:
      - {index: a, foo: {y: 3, z: 4}}
      - {index: b, foo: [Y1, Y2]}
    r: "{{ [list1, list2] | community.general.lists_mergeby('index') }}"

#  r:
#    - {index: a, foo: {y: 3, z: 4}}
#    - {index: b, foo: [Y1, Y2]}

- name: Example 7. Merge two lists. Merge nested dictionaries too.
  ansible.builtin.debug:
    var: r
  vars:
    list1:
      - {index: a, foo: {x: 1, y: 2}}
      - {index: b, foo: [X1, X2]}
    list2:
      - {index: a, foo: {y: 3, z: 4}}
      - {index: b, foo: [Y1, Y2]}
    r: "{{ [list1, list2] | community.general.lists_mergeby('index', recursive=true) }}"

#  r:
#    - {index: a, foo: {x:1, y: 3, z: 4}}
#    - {index: b, foo: [Y1, Y2]}

Return Value

Key

Description

Return value

list / elements=dictionary

The merged list.

Returned: success

Authors

  • Vladimir Botka (@vbotka)

Hint

Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.