..
  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

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.

.. 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>`.

Let us use the lists below in the following examples:

.. code-block:: yaml

  {{ lookup('file', 'default-common.yml')|indent(2) }}

{% for i in examples[0:2] %}
{{ i.label }}

.. code-block:: {{ i.lang }}

  {{ lookup('file', i.file)|indent(2) }}

{% endfor %}

.. versionadded:: 2.0.0

{% for i in examples[2:4] %}
{{ i.label }}

.. code-block:: {{ i.lang }}

  {{ lookup('file', i.file)|indent(2) }}

{% 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.

**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``.

**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.

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.

Let us use the lists below in the following examples

.. code-block:: yaml

  {{ lookup('file', 'default-recursive-true.yml')|indent(2) }}

{% for i in examples[4:16] %}
{{ i.label }}

.. code-block:: {{ i.lang }}

  {{ lookup('file', i.file)|indent(2) }}

{% endfor %}
