2022-08-08 08:44:19 +02:00
..
Copyright (c) Ansible Project
GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
SPDX-License-Identifier: GPL-3.0-or-later
2022-01-31 05:55:23 +01:00
Merging lists of dictionaries
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2023-10-30 22:54:58 +01:00
If you have two or more lists of dictionaries and want to combine them into a list of merged dictionaries, where the dictionaries are merged by an attribute, you can use the :ansplugin: `community.general.lists_mergeby filter <community.general.lists_mergeby#filter>` .
2022-01-31 05:55:23 +01:00
.. note :: The output of the examples in this section use the YAML callback plugin. Quoting: "Ansible output that can be quite a bit easier to read than the default JSON formatting." See :ref: `the documentation for the community.general.yaml callback plugin <ansible_collections.community.general.yaml_callback>` .
2022-02-05 21:20:15 +01:00
Let us use the lists below in the following examples:
.. code-block :: yaml
list1:
- name: foo
extra: true
- name: bar
extra: false
- name: meh
extra: true
list2:
- name: foo
path: /foo
- name: baz
path: /baz
2022-01-31 05:55:23 +01:00
In the example below the lists are merged by the attribute `` name `` :
.. code-block :: yaml+jinja
2022-02-05 21:20:15 +01:00
list3: "{{ list1|
community.general.lists_mergeby(list2, 'name') }}"
2022-01-31 05:55:23 +01:00
This produces:
.. code-block :: yaml
list3:
- extra: false
name: bar
- name: baz
path: /baz
- extra: true
name: foo
path: /foo
- extra: true
name: meh
2022-02-05 21:20:15 +01:00
2022-01-31 05:55:23 +01:00
.. versionadded :: 2.0.0
It is possible to use a list of lists as an input of the filter:
.. code-block :: yaml+jinja
2022-02-05 21:20:15 +01:00
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name') }}"
2022-01-31 05:55:23 +01:00
This produces the same result as in the previous example:
.. code-block :: yaml
list3:
- extra: false
name: bar
- name: baz
path: /baz
- extra: true
name: foo
path: /foo
- extra: true
name: meh
2022-02-05 21:20:15 +01:00
2023-10-30 22:54:58 +01:00
The filter also accepts two optional parameters: :ansopt: `community.general.lists_mergeby#filter:recursive` and :ansopt: `community.general.lists_mergeby#filter:list_merge` . This is available since community.general 4.4.0.
2022-01-31 05:55:23 +01:00
**recursive**
2023-10-30 22:54:58 +01:00
Is a boolean, default to `` false `` . Should the :ansplugin: `community.general.lists_mergeby#filter` filter recursively merge nested hashes. Note: It does not depend on the value of the `` hash_behaviour `` setting in `` ansible.cfg `` .
2022-01-31 05:55:23 +01:00
**list_merge**
2023-10-30 22:54:58 +01:00
Is a string, its possible values are :ansval: `replace` (default), :ansval: `keep` , :ansval: `append` , :ansval: `prepend` , :ansval: `append_rp` or :ansval: `prepend_rp` . It modifies the behaviour of :ansplugin: `community.general.lists_mergeby#filter` when the hashes to merge contain arrays/lists.
2022-01-31 05:55:23 +01:00
2023-10-30 22:54:58 +01:00
The examples below set :ansopt: `community.general.lists_mergeby#filter:recursive=true` and display the differences among all six options of :ansopt: `community.general.lists_mergeby#filter:list_merge` . Functionality of the parameters is exactly the same as in the filter :ansplugin: `ansible.builtin.combine#filter` . See :ref: `Combining hashes/dictionaries <combine_filter>` to learn details about these options.
2022-01-31 05:55:23 +01:00
2022-02-05 21:20:15 +01:00
Let us use the lists below in the following examples
2022-01-31 05:55:23 +01:00
.. code-block :: yaml
2022-02-05 21:20:15 +01:00
list1:
2022-01-31 05:55:23 +01:00
- name: myname01
param01:
x: default_value
2022-02-05 21:20:15 +01:00
y: default_value
list:
- default_value
- name: myname02
param01: [1, 1, 2, 3]
list2:
- name: myname01
param01:
2022-01-31 05:55:23 +01:00
y: patch_value
z: patch_value
2022-02-05 21:20:15 +01:00
list:
- patch_value
2022-01-31 05:55:23 +01:00
- name: myname02
2022-02-05 21:20:15 +01:00
param01: [3, 4, 4, {key: value}]
2023-10-30 22:54:58 +01:00
Example :ansopt: `community.general.lists_mergeby#filter:list_merge=replace` (default):
2022-02-05 21:20:15 +01:00
.. code-block :: yaml+jinja
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name',
recursive=true) }}"
This produces:
.. code-block :: yaml
list3:
- name: myname01
param01:
list:
- patch_value
x: default_value
y: patch_value
z: patch_value
- name: myname02
param01:
- 3
- 4
- 4
- key: value
2022-01-31 05:55:23 +01:00
2023-10-30 22:54:58 +01:00
Example :ansopt: `community.general.lists_mergeby#filter:list_merge=keep` :
2022-01-31 05:55:23 +01:00
.. code-block :: yaml+jinja
2022-02-05 21:20:15 +01:00
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name',
recursive=true,
list_merge='keep') }}"
2022-01-31 05:55:23 +01:00
This produces:
.. code-block :: yaml
2022-02-05 21:20:15 +01:00
list3:
- name: myname01
param01:
list:
- default_value
x: default_value
y: patch_value
z: patch_value
- name: myname02
param01:
- 1
- 1
- 2
- 3
2022-01-31 05:55:23 +01:00
2023-10-30 22:54:58 +01:00
Example :ansopt: `community.general.lists_mergeby#filter:list_merge=append` :
2022-01-31 05:55:23 +01:00
.. code-block :: yaml+jinja
2022-02-05 21:20:15 +01:00
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name',
recursive=true,
list_merge='append') }}"
2022-01-31 05:55:23 +01:00
This produces:
.. code-block :: yaml
2022-02-05 21:20:15 +01:00
list3:
- name: myname01
param01:
list:
- default_value
- patch_value
x: default_value
y: patch_value
z: patch_value
- name: myname02
param01:
- 1
- 1
- 2
- 3
- 3
- 4
- 4
- key: value
2022-01-31 05:55:23 +01:00
2023-10-30 22:54:58 +01:00
Example :ansopt: `community.general.lists_mergeby#filter:list_merge=prepend` :
2022-01-31 05:55:23 +01:00
.. code-block :: yaml+jinja
2022-02-05 21:20:15 +01:00
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name',
recursive=true,
list_merge='prepend') }}"
2022-01-31 05:55:23 +01:00
This produces:
.. code-block :: yaml
2022-02-05 21:20:15 +01:00
list3:
- name: myname01
param01:
list:
- patch_value
- default_value
x: default_value
y: patch_value
z: patch_value
- name: myname02
param01:
- 3
- 4
- 4
- key: value
- 1
- 1
- 2
- 3
2022-01-31 05:55:23 +01:00
2023-10-30 22:54:58 +01:00
Example :ansopt: `community.general.lists_mergeby#filter:list_merge=append_rp` :
2022-01-31 05:55:23 +01:00
.. code-block :: yaml+jinja
2022-02-05 21:20:15 +01:00
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name',
recursive=true,
list_merge='append_rp') }}"
2022-01-31 05:55:23 +01:00
This produces:
.. code-block :: yaml
2022-02-05 21:20:15 +01:00
list3:
- name: myname01
param01:
list:
- default_value
- patch_value
x: default_value
y: patch_value
z: patch_value
- name: myname02
param01:
- 1
- 1
- 2
- 3
- 4
- 4
- key: value
2022-01-31 05:55:23 +01:00
2023-10-30 22:54:58 +01:00
Example :ansopt: `community.general.lists_mergeby#filter:list_merge=prepend_rp` :
2022-01-31 05:55:23 +01:00
.. code-block :: yaml+jinja
2022-02-05 21:20:15 +01:00
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name',
recursive=true,
list_merge='prepend_rp') }}"
2022-01-31 05:55:23 +01:00
This produces:
.. code-block :: yaml
2022-02-05 21:20:15 +01:00
list3:
- name: myname01
param01:
list:
- patch_value
- default_value
x: default_value
y: patch_value
z: patch_value
- name: myname02
param01:
- 3
- 4
- 4
- key: value
- 1
- 1
- 2