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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-06-12 19:47:18 +02: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 <community.general.lists_mergeby#filter>` filter.
2022-01-31 05:55:23 +01:00
2024-06-12 19:47:18 +02: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 the documentation for the :ansplugin: `community.general.yaml callback plugin <community.general.yaml#callback>` .
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:
.. code-block :: yaml
list1:
2024-06-12 19:47:18 +02:00
- {name: foo, extra: true}
- {name: bar, extra: false}
- {name: meh, extra: true}
2022-02-05 21:20:15 +01:00
list2:
2024-06-12 19:47:18 +02:00
- {name: foo, path: /foo}
- {name: baz, path: /baz}
2022-02-05 21:20:15 +01:00
2024-06-12 19:47:18 +02:00
Two lists
"""""""""
2022-01-31 05:55:23 +01:00
In the example below the lists are merged by the attribute `` name `` :
.. code-block :: yaml+jinja
2024-06-12 19:47:18 +02:00
list3: "{{ list1 |
2022-02-05 21:20:15 +01:00
community.general.lists_mergeby(list2, 'name') }}"
2022-01-31 05:55:23 +01:00
This produces:
.. code-block :: yaml
list3:
2024-06-12 19:47:18 +02:00
- {name: bar, extra: false}
- {name: baz, path: /baz}
- {name: foo, extra: true, path: /foo}
- {name: meh, extra: true}
2022-01-31 05:55:23 +01:00
2022-02-05 21:20:15 +01:00
2022-01-31 05:55:23 +01:00
.. versionadded :: 2.0.0
2024-06-12 19:47:18 +02:00
List of two lists
"""""""""""""""""
2022-01-31 05:55:23 +01:00
It is possible to use a list of lists as an input of the filter:
.. code-block :: yaml+jinja
2024-06-12 19:47:18 +02:00
list3: "{{ [list1, list2] |
2022-02-05 21:20:15 +01:00
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:
2024-06-12 19:47:18 +02:00
- {name: bar, extra: false}
- {name: baz, path: /baz}
- {name: foo, extra: true, path: /foo}
- {name: meh, extra: true}
Single list
"""""""""""
It is possible to merge single list:
.. code-block :: yaml+jinja
list3: "{{ [list1 + list2, []] |
community.general.lists_mergeby('name') }}"
This produces the same result as in the previous example:
.. code-block :: yaml
list3:
- {name: bar, extra: false}
- {name: baz, path: /baz}
- {name: foo, extra: true, path: /foo}
- {name: meh, extra: true}
2022-01-31 05:55:23 +01:00
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
2024-06-12 19:47:18 +02:00
list: [default_value]
2022-02-05 21:20:15 +01:00
- 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
2024-06-12 19:47:18 +02:00
list: [patch_value]
2022-01-31 05:55:23 +01:00
- name: myname02
2024-06-12 19:47:18 +02:00
param01: [3, 4, 4]
2022-02-05 21:20:15 +01:00
2024-06-12 19:47:18 +02:00
list_merge=replace (default)
""""""""""""""""""""""""""""
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
2024-06-12 19:47:18 +02:00
list3: "{{ [list1, list2] |
2022-02-05 21:20:15 +01:00
community.general.lists_mergeby('name',
recursive=true) }}"
This produces:
.. code-block :: yaml
list3:
2024-06-12 19:47:18 +02:00
- name: myname01
param01:
x: default_value
y: patch_value
list: [patch_value]
z: patch_value
- name: myname02
param01: [3, 4, 4]
2022-01-31 05:55:23 +01:00
2024-06-12 19:47:18 +02:00
list_merge=keep
"""""""""""""""
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
2024-06-12 19:47:18 +02:00
list3: "{{ [list1, list2] |
2022-02-05 21:20:15 +01:00
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:
2024-06-12 19:47:18 +02:00
- name: myname01
param01:
x: default_value
y: patch_value
list: [default_value]
z: patch_value
- name: myname02
param01: [1, 1, 2, 3]
2022-01-31 05:55:23 +01:00
2024-06-12 19:47:18 +02:00
list_merge=append
"""""""""""""""""
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
2024-06-12 19:47:18 +02:00
list3: "{{ [list1, list2] |
2022-02-05 21:20:15 +01:00
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:
2024-06-12 19:47:18 +02:00
- name: myname01
param01:
x: default_value
y: patch_value
list: [default_value, patch_value]
z: patch_value
- name: myname02
param01: [1, 1, 2, 3, 3, 4, 4]
2022-01-31 05:55:23 +01:00
2024-06-12 19:47:18 +02:00
list_merge=prepend
""""""""""""""""""
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
2024-06-12 19:47:18 +02:00
list3: "{{ [list1, list2] |
2022-02-05 21:20:15 +01:00
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:
2024-06-12 19:47:18 +02:00
- name: myname01
param01:
x: default_value
y: patch_value
list: [patch_value, default_value]
z: patch_value
- name: myname02
param01: [3, 4, 4, 1, 1, 2, 3]
2022-01-31 05:55:23 +01:00
2024-06-12 19:47:18 +02:00
list_merge=append_rp
""""""""""""""""""""
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
2024-06-12 19:47:18 +02:00
list3: "{{ [list1, list2] |
2022-02-05 21:20:15 +01:00
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:
2024-06-12 19:47:18 +02:00
- name: myname01
param01:
x: default_value
y: patch_value
list: [default_value, patch_value]
z: patch_value
- name: myname02
param01: [1, 1, 2, 3, 4, 4]
2022-01-31 05:55:23 +01:00
2024-06-12 19:47:18 +02:00
list_merge=prepend_rp
"""""""""""""""""""""
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
2024-06-12 19:47:18 +02:00
list3: "{{ [list1, list2] |
2022-02-05 21:20:15 +01:00
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:
2024-06-12 19:47:18 +02:00
- name: myname01
param01:
x: default_value
y: patch_value
list: [patch_value, default_value]
z: patch_value
- name: myname02
param01: [3, 4, 4, 1, 1, 2]
2022-02-05 21:20:15 +01:00