1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

[PR #8477/ac3c0435 backport][stable-9] Update docsite chapter "Merging lists of dictionaries" (#8492)

Update docsite chapter "Merging lists of dictionaries" (#8477)

* Update docs 'Merging lists of dictionaries'

* Adding links to module and plugin options in
  docs/docsite/helper/lists_mergeby
* Add subsections and improve formatting.
* Add example-009 'Merge single list'

* Fix licenses.

* Fix variables.

* Update docs/docsite/helper/lists_mergeby/filter_guide_abstract_informations_merging_lists_of_dictionaries.rst.j2

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update docs/docsite/rst/filter_guide_abstract_informations_merging_lists_of_dictionaries.rst

Co-authored-by: Felix Fontein <felix@fontein.de>

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit ac3c04357c)

Co-authored-by: Vladimir Botka <vbotka@gmail.com>
This commit is contained in:
patchback[bot] 2024-06-13 07:19:02 +02:00 committed by GitHub
parent 8e79844b75
commit 42175e38b2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
28 changed files with 238 additions and 219 deletions

View file

@ -2,17 +2,11 @@
# Copyright (c) Ansible Project # 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) # 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 # SPDX-License-Identifier: GPL-3.0-or-later
list1: list1:
- name: foo - {name: foo, extra: true}
extra: true - {name: bar, extra: false}
- name: bar - {name: meh, extra: true}
extra: false
- name: meh
extra: true
list2: list2:
- name: foo - {name: foo, path: /foo}
path: /foo - {name: baz, path: /baz}
- name: baz
path: /baz

View file

@ -2,14 +2,12 @@
# Copyright (c) Ansible Project # 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) # 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 # SPDX-License-Identifier: GPL-3.0-or-later
list1: list1:
- name: myname01 - name: myname01
param01: param01:
x: default_value x: default_value
y: default_value y: default_value
list: list: [default_value]
- default_value
- name: myname02 - name: myname02
param01: [1, 1, 2, 3] param01: [1, 1, 2, 3]
@ -18,7 +16,6 @@ list2:
param01: param01:
y: patch_value y: patch_value
z: patch_value z: patch_value
list: list: [patch_value]
- patch_value
- name: myname02 - name: myname02
param01: [3, 4, 4, {key: value}] param01: [3, 4, 4]

View file

@ -8,7 +8,7 @@
dir: example-001_vars dir: example-001_vars
- debug: - debug:
var: list3 var: list3
when: debug|d(false)|bool when: debug | d(false) | bool
- template: - template:
src: list3.out.j2 src: list3.out.j2
dest: example-001.out dest: example-001.out

View file

@ -2,6 +2,5 @@
# Copyright (c) Ansible Project # 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) # 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 # SPDX-License-Identifier: GPL-3.0-or-later
list3: "{{ list1 |
list3: "{{ list1|
community.general.lists_mergeby(list2, 'name') }}" community.general.lists_mergeby(list2, 'name') }}"

View file

@ -8,7 +8,7 @@
dir: example-002_vars dir: example-002_vars
- debug: - debug:
var: list3 var: list3
when: debug|d(false)|bool when: debug | d(false) | bool
- template: - template:
src: list3.out.j2 src: list3.out.j2
dest: example-002.out dest: example-002.out

View file

@ -2,6 +2,5 @@
# Copyright (c) Ansible Project # 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) # 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 # SPDX-License-Identifier: GPL-3.0-or-later
list3: "{{ [list1, list2] |
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name') }}" community.general.lists_mergeby('name') }}"

View file

@ -8,7 +8,7 @@
dir: example-003_vars dir: example-003_vars
- debug: - debug:
var: list3 var: list3
when: debug|d(false)|bool when: debug | d(false) | bool
- template: - template:
src: list3.out.j2 src: list3.out.j2
dest: example-003.out dest: example-003.out

View file

@ -2,7 +2,6 @@
# Copyright (c) Ansible Project # 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) # 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 # SPDX-License-Identifier: GPL-3.0-or-later
list3: "{{ [list1, list2] |
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true) }}" recursive=true) }}"

View file

@ -8,7 +8,7 @@
dir: example-004_vars dir: example-004_vars
- debug: - debug:
var: list3 var: list3
when: debug|d(false)|bool when: debug | d(false) | bool
- template: - template:
src: list3.out.j2 src: list3.out.j2
dest: example-004.out dest: example-004.out

View file

@ -2,8 +2,7 @@
# Copyright (c) Ansible Project # 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) # 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 # SPDX-License-Identifier: GPL-3.0-or-later
list3: "{{ [list1, list2] |
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true, recursive=true,
list_merge='keep') }}" list_merge='keep') }}"

View file

@ -8,7 +8,7 @@
dir: example-005_vars dir: example-005_vars
- debug: - debug:
var: list3 var: list3
when: debug|d(false)|bool when: debug | d(false) | bool
- template: - template:
src: list3.out.j2 src: list3.out.j2
dest: example-005.out dest: example-005.out

View file

@ -2,8 +2,7 @@
# Copyright (c) Ansible Project # 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) # 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 # SPDX-License-Identifier: GPL-3.0-or-later
list3: "{{ [list1, list2] |
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true, recursive=true,
list_merge='append') }}" list_merge='append') }}"

View file

@ -8,7 +8,7 @@
dir: example-006_vars dir: example-006_vars
- debug: - debug:
var: list3 var: list3
when: debug|d(false)|bool when: debug | d(false) | bool
- template: - template:
src: list3.out.j2 src: list3.out.j2
dest: example-006.out dest: example-006.out

View file

@ -2,8 +2,7 @@
# Copyright (c) Ansible Project # 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) # 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 # SPDX-License-Identifier: GPL-3.0-or-later
list3: "{{ [list1, list2] |
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true, recursive=true,
list_merge='prepend') }}" list_merge='prepend') }}"

View file

@ -8,7 +8,7 @@
dir: example-007_vars dir: example-007_vars
- debug: - debug:
var: list3 var: list3
when: debug|d(false)|bool when: debug|d(false) | bool
- template: - template:
src: list3.out.j2 src: list3.out.j2
dest: example-007.out dest: example-007.out

View file

@ -2,8 +2,7 @@
# Copyright (c) Ansible Project # 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) # 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 # SPDX-License-Identifier: GPL-3.0-or-later
list3: "{{ [list1, list2] |
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true, recursive=true,
list_merge='append_rp') }}" list_merge='append_rp') }}"

View file

@ -8,7 +8,7 @@
dir: example-008_vars dir: example-008_vars
- debug: - debug:
var: list3 var: list3
when: debug|d(false)|bool when: debug | d(false) | bool
- template: - template:
src: list3.out.j2 src: list3.out.j2
dest: example-008.out dest: example-008.out

View file

@ -2,8 +2,7 @@
# Copyright (c) Ansible Project # 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) # 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 # SPDX-License-Identifier: GPL-3.0-or-later
list3: "{{ [list1, list2] |
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true, recursive=true,
list_merge='prepend_rp') }}" list_merge='prepend_rp') }}"

View file

@ -0,0 +1,14 @@
---
# 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
- name: 9. Merge single list by common attribute 'name'
include_vars:
dir: example-009_vars
- debug:
var: list3
when: debug | d(false) | bool
- template:
src: list3.out.j2
dest: example-009.out

View file

@ -0,0 +1 @@
../default-common.yml

View file

@ -0,0 +1,6 @@
---
# 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
list3: "{{ [list1 + list2, []] |
community.general.lists_mergeby('name') }}"

View file

@ -4,51 +4,75 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
examples: examples:
- label: 'In the example below the lists are merged by the attribute ``name``:' - title: Two lists
description: 'In the example below the lists are merged by the attribute ``name``:'
file: example-001_vars/list3.yml file: example-001_vars/list3.yml
lang: 'yaml+jinja' lang: 'yaml+jinja'
- label: 'This produces:' - title:
description: 'This produces:'
file: example-001.out file: example-001.out
lang: 'yaml' lang: 'yaml'
- label: 'It is possible to use a list of lists as an input of the filter:' - title: List of two lists
description: 'It is possible to use a list of lists as an input of the filter:'
file: example-002_vars/list3.yml file: example-002_vars/list3.yml
lang: 'yaml+jinja' lang: 'yaml+jinja'
- label: 'This produces the same result as in the previous example:' - title:
description: 'This produces the same result as in the previous example:'
file: example-002.out file: example-002.out
lang: 'yaml' lang: 'yaml'
- label: 'Example ``list_merge=replace`` (default):' - title: Single list
description: 'It is possible to merge single list:'
file: example-009_vars/list3.yml
lang: 'yaml+jinja'
- title:
description: 'This produces the same result as in the previous example:'
file: example-009.out
lang: 'yaml'
- title: list_merge=replace (default)
description: 'Example :ansopt:`community.general.lists_mergeby#filter:list_merge=replace` (default):'
file: example-003_vars/list3.yml file: example-003_vars/list3.yml
lang: 'yaml+jinja' lang: 'yaml+jinja'
- label: 'This produces:' - title:
description: 'This produces:'
file: example-003.out file: example-003.out
lang: 'yaml' lang: 'yaml'
- label: 'Example ``list_merge=keep``:' - title: list_merge=keep
description: 'Example :ansopt:`community.general.lists_mergeby#filter:list_merge=keep`:'
file: example-004_vars/list3.yml file: example-004_vars/list3.yml
lang: 'yaml+jinja' lang: 'yaml+jinja'
- label: 'This produces:' - title:
description: 'This produces:'
file: example-004.out file: example-004.out
lang: 'yaml' lang: 'yaml'
- label: 'Example ``list_merge=append``:' - title: list_merge=append
description: 'Example :ansopt:`community.general.lists_mergeby#filter:list_merge=append`:'
file: example-005_vars/list3.yml file: example-005_vars/list3.yml
lang: 'yaml+jinja' lang: 'yaml+jinja'
- label: 'This produces:' - title:
description: 'This produces:'
file: example-005.out file: example-005.out
lang: 'yaml' lang: 'yaml'
- label: 'Example ``list_merge=prepend``:' - title: list_merge=prepend
description: 'Example :ansopt:`community.general.lists_mergeby#filter:list_merge=prepend`:'
file: example-006_vars/list3.yml file: example-006_vars/list3.yml
lang: 'yaml+jinja' lang: 'yaml+jinja'
- label: 'This produces:' - title:
description: 'This produces:'
file: example-006.out file: example-006.out
lang: 'yaml' lang: 'yaml'
- label: 'Example ``list_merge=append_rp``:' - title: list_merge=append_rp
description: 'Example :ansopt:`community.general.lists_mergeby#filter:list_merge=append_rp`:'
file: example-007_vars/list3.yml file: example-007_vars/list3.yml
lang: 'yaml+jinja' lang: 'yaml+jinja'
- label: 'This produces:' - title:
description: 'This produces:'
file: example-007.out file: example-007.out
lang: 'yaml' lang: 'yaml'
- label: 'Example ``list_merge=prepend_rp``:' - title: list_merge=prepend_rp
description: 'Example :ansopt:`community.general.lists_mergeby#filter:list_merge=prepend_rp`:'
file: example-008_vars/list3.yml file: example-008_vars/list3.yml
lang: 'yaml+jinja' lang: 'yaml+jinja'
- label: 'This produces:' - title:
description: 'This produces:'
file: example-008.out file: example-008.out
lang: 'yaml' lang: 'yaml'

View file

@ -4,10 +4,10 @@
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-or-later
{% for i in examples %} {% for i in examples %}
{{ i.label }} {{ i.description }}
.. code-block:: {{ i.lang }} .. code-block:: {{ i.lang }}
{{ lookup('file', i.file)|indent(2) }} {{ lookup('file', i.file) | split('\n') | reject('match', '^(#|---)') | join ('\n') | indent(2) }}
{% endfor %} {% endfor %}

View file

@ -0,0 +1,7 @@
---
# 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
examples_one: true
examples_all: true
merging_lists_of_dictionaries: true

View file

@ -6,57 +6,69 @@
Merging lists of dictionaries Merging lists of dictionaries
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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 ``lists_mergeby`` filter. 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.
.. 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>`. .. 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>`.
Let us use the lists below in the following examples: Let us use the lists below in the following examples:
.. code-block:: yaml .. code-block:: yaml
{{ lookup('file', 'default-common.yml')|indent(2) }} {{ lookup('file', 'default-common.yml') | split('\n') | reject('match', '^(#|---)') | join ('\n') | indent(2) }}
{% for i in examples[0:2] %} {% for i in examples[0:2] %}
{{ i.label }} {% if i.title | d('', true) | length > 0 %}
{{ i.title }}
{{ "%s" % ('"' * i.title|length) }}
{% endif %}
{{ i.description }}
.. code-block:: {{ i.lang }} .. code-block:: {{ i.lang }}
{{ lookup('file', i.file)|indent(2) }} {{ lookup('file', i.file) | split('\n') | reject('match', '^(#|---)') | join ('\n') | indent(2) }}
{% endfor %} {% endfor %}
.. versionadded:: 2.0.0 .. versionadded:: 2.0.0
{% for i in examples[2:4] %} {% for i in examples[2:6] %}
{{ i.label }} {% if i.title | d('', true) | length > 0 %}
{{ i.title }}
{{ "%s" % ('"' * i.title|length) }}
{% endif %}
{{ i.description }}
.. code-block:: {{ i.lang }} .. code-block:: {{ i.lang }}
{{ lookup('file', i.file)|indent(2) }} {{ lookup('file', i.file) | split('\n') | reject('match', '^(#|---)') | join ('\n') | indent(2) }}
{% endfor %} {% endfor %}
The filter also accepts two optional parameters: ``recursive`` and ``list_merge``. These parameters are only supported when used with ansible-base 2.10 or ansible-core, but not with Ansible 2.9. This is available since community.general 4.4.0. 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.
**recursive** **recursive**
Is a boolean, default to ``False``. Should the ``community.general.lists_mergeby`` recursively merge nested hashes. Note: It does not depend on the value of the ``hash_behaviour`` setting in ``ansible.cfg``. 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``.
**list_merge** **list_merge**
Is a string, its possible values are ``replace`` (default), ``keep``, ``append``, ``prepend``, ``append_rp`` or ``prepend_rp``. It modifies the behaviour of ``community.general.lists_mergeby`` when the hashes to merge contain arrays/lists. 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.
The examples below set ``recursive=true`` and display the differences among all six options of ``list_merge``. Functionality of the parameters is exactly the same as in the filter ``combine``. See :ref:`Combining hashes/dictionaries <combine_filter>` to learn details about these options. 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.
Let us use the lists below in the following examples Let us use the lists below in the following examples
.. code-block:: yaml .. code-block:: yaml
{{ lookup('file', 'default-recursive-true.yml')|indent(2) }} {{ lookup('file', 'default-recursive-true.yml') | split('\n') | reject('match', '^(#|---)') | join ('\n') |indent(2) }}
{% for i in examples[4:16] %} {% for i in examples[6:] %}
{{ i.label }} {% if i.title | d('', true) | length > 0 %}
{{ i.title }}
{{ "%s" % ('"' * i.title|length) }}
{% endif %}
{{ i.description }}
.. code-block:: {{ i.lang }} .. code-block:: {{ i.lang }}
{{ lookup('file', i.file)|indent(2) }} {{ lookup('file', i.file) | split('\n') | reject('match', '^(#|---)') | join ('\n') |indent(2) }}
{% endfor %} {% endfor %}

View file

@ -4,4 +4,4 @@ GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://w
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-or-later
#} #}
list3: list3:
{{ list3|to_nice_yaml(indent=0) }} {{ list3 | to_yaml(indent=2, sort_keys=false) | indent(2) }}

View file

@ -5,7 +5,7 @@
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# 1) Run all examples and create example-XXX.out # 1) Run all examples and create example-XXX.out
# shell> ansible-playbook playbook.yml -e examples=true # shell> ansible-playbook playbook.yml -e examples_one=true
# #
# 2) Optionally, for testing, create examples_all.rst # 2) Optionally, for testing, create examples_all.rst
# shell> ansible-playbook playbook.yml -e examples_all=true # shell> ansible-playbook playbook.yml -e examples_all=true
@ -45,18 +45,20 @@
tags: t007 tags: t007
- import_tasks: example-008.yml - import_tasks: example-008.yml
tags: t008 tags: t008
when: examples|d(false)|bool - import_tasks: example-009.yml
tags: t009
when: examples_one | d(false) | bool
- block: - block:
- include_vars: examples.yml - include_vars: examples.yml
- template: - template:
src: examples_all.rst.j2 src: examples_all.rst.j2
dest: examples_all.rst dest: examples_all.rst
when: examples_all|d(false)|bool when: examples_all | d(false) | bool
- block: - block:
- include_vars: examples.yml - include_vars: examples.yml
- template: - template:
src: filter_guide_abstract_informations_merging_lists_of_dictionaries.rst.j2 src: filter_guide_abstract_informations_merging_lists_of_dictionaries.rst.j2
dest: filter_guide_abstract_informations_merging_lists_of_dictionaries.rst dest: filter_guide_abstract_informations_merging_lists_of_dictionaries.rst
when: merging_lists_of_dictionaries|d(false)|bool when: merging_lists_of_dictionaries | d(false) | bool

View file

@ -6,33 +6,30 @@
Merging lists of dictionaries Merging lists of dictionaries
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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>`. 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.
.. 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>`. .. 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>`.
Let us use the lists below in the following examples: Let us use the lists below in the following examples:
.. code-block:: yaml .. code-block:: yaml
list1: list1:
- name: foo - {name: foo, extra: true}
extra: true - {name: bar, extra: false}
- name: bar - {name: meh, extra: true}
extra: false
- name: meh
extra: true
list2: list2:
- name: foo - {name: foo, path: /foo}
path: /foo - {name: baz, path: /baz}
- name: baz
path: /baz
Two lists
"""""""""
In the example below the lists are merged by the attribute ``name``: In the example below the lists are merged by the attribute ``name``:
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
list3: "{{ list1| list3: "{{ list1 |
community.general.lists_mergeby(list2, 'name') }}" community.general.lists_mergeby(list2, 'name') }}"
This produces: This produces:
@ -40,24 +37,21 @@ This produces:
.. code-block:: yaml .. code-block:: yaml
list3: list3:
- extra: false - {name: bar, extra: false}
name: bar - {name: baz, path: /baz}
- name: baz - {name: foo, extra: true, path: /foo}
path: /baz - {name: meh, extra: true}
- extra: true
name: foo
path: /foo
- extra: true
name: meh
.. versionadded:: 2.0.0 .. versionadded:: 2.0.0
List of two lists
"""""""""""""""""
It is possible to use a list of lists as an input of the filter: It is possible to use a list of lists as an input of the filter:
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
list3: "{{ [list1, list2]| list3: "{{ [list1, list2] |
community.general.lists_mergeby('name') }}" community.general.lists_mergeby('name') }}"
This produces the same result as in the previous example: This produces the same result as in the previous example:
@ -65,15 +59,29 @@ This produces the same result as in the previous example:
.. code-block:: yaml .. code-block:: yaml
list3: list3:
- extra: false - {name: bar, extra: false}
name: bar - {name: baz, path: /baz}
- name: baz - {name: foo, extra: true, path: /foo}
path: /baz - {name: meh, extra: true}
- extra: true
name: foo Single list
path: /foo """""""""""
- extra: true It is possible to merge single list:
name: meh
.. 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}
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. 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.
@ -95,8 +103,7 @@ Let us use the lists below in the following examples
param01: param01:
x: default_value x: default_value
y: default_value y: default_value
list: list: [default_value]
- default_value
- name: myname02 - name: myname02
param01: [1, 1, 2, 3] param01: [1, 1, 2, 3]
@ -105,16 +112,17 @@ Let us use the lists below in the following examples
param01: param01:
y: patch_value y: patch_value
z: patch_value z: patch_value
list: list: [patch_value]
- patch_value
- name: myname02 - name: myname02
param01: [3, 4, 4, {key: value}] param01: [3, 4, 4]
list_merge=replace (default)
""""""""""""""""""""""""""""
Example :ansopt:`community.general.lists_mergeby#filter:list_merge=replace` (default): Example :ansopt:`community.general.lists_mergeby#filter:list_merge=replace` (default):
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
list3: "{{ [list1, list2]| list3: "{{ [list1, list2] |
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true) }}" recursive=true) }}"
@ -123,25 +131,22 @@ This produces:
.. code-block:: yaml .. code-block:: yaml
list3: list3:
- name: myname01 - name: myname01
param01: param01:
list: x: default_value
- patch_value y: patch_value
x: default_value list: [patch_value]
y: patch_value z: patch_value
z: patch_value - name: myname02
- name: myname02 param01: [3, 4, 4]
param01:
- 3
- 4
- 4
- key: value
list_merge=keep
"""""""""""""""
Example :ansopt:`community.general.lists_mergeby#filter:list_merge=keep`: Example :ansopt:`community.general.lists_mergeby#filter:list_merge=keep`:
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
list3: "{{ [list1, list2]| list3: "{{ [list1, list2] |
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true, recursive=true,
list_merge='keep') }}" list_merge='keep') }}"
@ -151,25 +156,22 @@ This produces:
.. code-block:: yaml .. code-block:: yaml
list3: list3:
- name: myname01 - name: myname01
param01: param01:
list: x: default_value
- default_value y: patch_value
x: default_value list: [default_value]
y: patch_value z: patch_value
z: patch_value - name: myname02
- name: myname02 param01: [1, 1, 2, 3]
param01:
- 1
- 1
- 2
- 3
list_merge=append
"""""""""""""""""
Example :ansopt:`community.general.lists_mergeby#filter:list_merge=append`: Example :ansopt:`community.general.lists_mergeby#filter:list_merge=append`:
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
list3: "{{ [list1, list2]| list3: "{{ [list1, list2] |
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true, recursive=true,
list_merge='append') }}" list_merge='append') }}"
@ -179,30 +181,22 @@ This produces:
.. code-block:: yaml .. code-block:: yaml
list3: list3:
- name: myname01 - name: myname01
param01: param01:
list: x: default_value
- default_value y: patch_value
- patch_value list: [default_value, patch_value]
x: default_value z: patch_value
y: patch_value - name: myname02
z: patch_value param01: [1, 1, 2, 3, 3, 4, 4]
- name: myname02
param01:
- 1
- 1
- 2
- 3
- 3
- 4
- 4
- key: value
list_merge=prepend
""""""""""""""""""
Example :ansopt:`community.general.lists_mergeby#filter:list_merge=prepend`: Example :ansopt:`community.general.lists_mergeby#filter:list_merge=prepend`:
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
list3: "{{ [list1, list2]| list3: "{{ [list1, list2] |
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true, recursive=true,
list_merge='prepend') }}" list_merge='prepend') }}"
@ -212,30 +206,22 @@ This produces:
.. code-block:: yaml .. code-block:: yaml
list3: list3:
- name: myname01 - name: myname01
param01: param01:
list: x: default_value
- patch_value y: patch_value
- default_value list: [patch_value, default_value]
x: default_value z: patch_value
y: patch_value - name: myname02
z: patch_value param01: [3, 4, 4, 1, 1, 2, 3]
- name: myname02
param01:
- 3
- 4
- 4
- key: value
- 1
- 1
- 2
- 3
list_merge=append_rp
""""""""""""""""""""
Example :ansopt:`community.general.lists_mergeby#filter:list_merge=append_rp`: Example :ansopt:`community.general.lists_mergeby#filter:list_merge=append_rp`:
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
list3: "{{ [list1, list2]| list3: "{{ [list1, list2] |
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true, recursive=true,
list_merge='append_rp') }}" list_merge='append_rp') }}"
@ -245,29 +231,22 @@ This produces:
.. code-block:: yaml .. code-block:: yaml
list3: list3:
- name: myname01 - name: myname01
param01: param01:
list: x: default_value
- default_value y: patch_value
- patch_value list: [default_value, patch_value]
x: default_value z: patch_value
y: patch_value - name: myname02
z: patch_value param01: [1, 1, 2, 3, 4, 4]
- name: myname02
param01:
- 1
- 1
- 2
- 3
- 4
- 4
- key: value
list_merge=prepend_rp
"""""""""""""""""""""
Example :ansopt:`community.general.lists_mergeby#filter:list_merge=prepend_rp`: Example :ansopt:`community.general.lists_mergeby#filter:list_merge=prepend_rp`:
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
list3: "{{ [list1, list2]| list3: "{{ [list1, list2] |
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true, recursive=true,
list_merge='prepend_rp') }}" list_merge='prepend_rp') }}"
@ -277,21 +256,12 @@ This produces:
.. code-block:: yaml .. code-block:: yaml
list3: list3:
- name: myname01 - name: myname01
param01: param01:
list: x: default_value
- patch_value y: patch_value
- default_value list: [patch_value, default_value]
x: default_value z: patch_value
y: patch_value - name: myname02
z: patch_value param01: [3, 4, 4, 1, 1, 2]
- name: myname02
param01:
- 3
- 4
- 4
- key: value
- 1
- 1
- 2