10

I have a task which uses with_subelements but it's terrible slow for big list (especially that most of the elements has duplicates and I don't need to run it multiple times for them).

So I'm looking for a way to optimize it somehow. I wish to get all unique elements from that list - let say settings in the example below:

inventory:

my_list:
  - { name: foo, settings: ['x', 'y', 'z'] }      
  - { name: bar, settings: ['x', 'y', 'q', 'w'] }

tasks:

- name: get all settings
  set_fact:
    all_settings="{{ my_list|map(attribute='settings')|list }}"

- name: show results
  debug:
    var=all_settings

results:

"var": {
        "all_settings": [
            [
                "x",
                "y",
                "z"
            ],
            [
                "x",
                "y",
                "q"
                "w"
            ]
        ]
    }

I stuck at this point. How can I combine those list together ?

I'm looking for a way to get ['x', 'y', 'z', 'q', 'w']

pawel7318
  • 213
  • 1
  • 2
  • 11

3 Answers3

8

You need to use a union.

Off the top of my head:

all_settings="{{ foo|map(attribute='settings')|union(bar|map(attribute='settings')) }}"
Michael Hampton
  • 244,070
  • 43
  • 506
  • 972
  • The problem is that I can't loop on `my_list` elements manually. It's just an example with two elements for simplicity but normally I have much more. – pawel7318 Nov 17 '15 at 16:07
  • Perhaps you should explain what you're _really_ trying to do. – Michael Hampton Nov 17 '15 at 16:11
  • I think it's quite clear from the post. `flatten` does the trick since it will combine a list of lists of any size into a single list as opposed to `union` which combines just two lists. – Frans Feb 23 '22 at 08:48
2

What about this ?

- name: get all settings
  set_fact:
    all_settings="{{ my_list|map(attribute='settings')|list|flatten|unique }}"
fraff
  • 121
  • 2
0

Looks like this should work:

...
all_settings="{{ my_list|map(attribute='settings')|list | sum(start=[]) | unique }}"
Vitalii T
  • 101