community.general icon indicating copy to clipboard operation
community.general copied to clipboard

Add new filters to calculate the union, intersection, difference and symmetric difference of lists by preserving the items order

Open cfiehe opened this issue 1 year ago • 6 comments

Summary

The behavioral change in the builtin filters ansible.builtin.union, ansible.builtin.intersect, ansible.builtin.difference and ansible.builtin.symmetric_difference introduced in Ansible Core 2.16 forces many people including myself to migrate their code in order to stay compatible with the current release: https://github.com/ansible/ansible/issues/82554

Starting from Ansible Core 2.16, the builtin filters do no longer preserve the item order, so that the result is unpredictable. This is unwanted in some cases. It is possible to workaround the problem e.g. by replacing a | union(b) with (a + b) | unique, but especially in complex statements where the union filter is involved and where ordering is important, you must have an eye on the operator precedencies. The whole code rewriting process is error-prone and statements become ugly and hard to read. In those cases, it would be nice to have replacing filters for the ansible.builtin.union, ansible.builtin.intersect, ansible.builtin.difference and ansible.builtin.symmetric_difference which behave in the same way as they did before Ansible Core 2.16.

Issue Type

Feature Idea

Component Name

lists_union, lists_intersect, lists_difference, symmetric_difference

Additional Information

---
- name: Filter test
  hosts: all
  become: true
  gather_facts: false
  vars:
    list1: [1, 2, 5, 3, 4, 10]
    list2: [1, 2, 3, 4, 5, 11, 99]
    list3: [1, 2, 3, 4, 5, 10, 99, 101]
  tasks:
    - name: Example for community.general.lists_union
      ansible.builtin.debug:
        msg: "{{ list1 | community.general.lists_union(list2, list3) }}"
    # => [1, 2, 5, 3, 4, 10, 11, 99, 101]

    - name: Example for community.general.lists_intersect
      ansible.builtin.debug:
        msg: "{{ list1 | community.general.lists_intersect(list2, list3) }}"
    # => [1, 2, 5, 3, 4]

    - name: Example for community.general.lists_difference
      ansible.builtin.debug:
        msg: "{{ list1 | community.general.lists_difference(list2, list3) }}"
    # => []

Code of Conduct

  • [X] I agree to follow the Ansible Code of Conduct

cfiehe avatar Feb 18 '24 21:02 cfiehe

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help

ansibullbot avatar Feb 18 '24 21:02 ansibullbot

cc @hryamzik @obourdon click here for bot help

ansibullbot avatar Feb 18 '24 21:02 ansibullbot

!component -plugins/modules/interfaces_file.py

felixfontein avatar Feb 18 '24 21:02 felixfontein

Sounds like a good idea to me! Do you want to work on this, or are you hoping that someone else will do this?

felixfontein avatar Feb 18 '24 21:02 felixfontein

I have created a feature pull request for those filters. I hope, that the code will pass the review 😃.

cfiehe avatar Feb 18 '24 21:02 cfiehe

Files identified in the description: None

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help

ansibullbot avatar Feb 18 '24 21:02 ansibullbot