skip to Main Content

I’m parsing some values using json_query. After extracting the values I’m left with a list of elements which contain the list of values. My goal is to have a single list of un-nested values.
How can I achieve this?

E.g.:

my_list: [ [1,2],[3,4],[5,6] ]

Should become

my_list: [1,2,3,4,5,6]

I can’t use my_list[0] | union([my_list[1]) | union(my_list[2]) because the my_list is dynamic.

2

Answers


  1. You can use a custom plugin to handle Python-like jobs easily. To do this, create a folder named filter_plugins (make sure to use this reserved name) in the same folder as your playbook, and add your Python filter there.

    $ tree
    ├── nested_list.yml
    ├── filter_plugins
    │   └── nested_union.py
    └── inventory
    

    Make sure the filter contains the FilterModule class and filters method:

    $ cat nested_union.py
    class FilterModule(object):
        def filters(self):
            return {
                'nested_union': self.nested_union,
            }
    
        def nested_union(self, nested_list):
            return [x for inner_list in nested_list for x in inner_list]
    

    Call the new filter from your Ansible playbook:

    ---
    - name: 
      hosts: local
      tasks:
        - name: Union merged lists
          vars: 
            my_list: [ [1,2],[3,4],[5,6] ]
          set_fact:
            new_list: "{{ my_list | nested_union }}"
    ...
    

    Here is the inventory file, just for reference and to complete the example:

    [local]
    127.0.0.1 ansible_connection=local
    

    And here is the result of the execution:

    $ ansible-playbook -i inventory nested_list.yml -v
    
    -- snip --
    
    TASK [Union merged lists]
    ok: [127.0.0.1] => {"ansible_facts": {"new_list": [1, 2, 3, 4, 5, 6]}, "changed": false}
    
    Login or Signup to reply.
  2. Use the flatten filter.

    Given:

    - debug:
        msg: "{{ [ [1,2],[3,4],[5,6] ] | flatten(1) }}"
    

    This yields the expected list:

    ok: [localhost] => 
      msg:
      - 1
      - 2
      - 3
      - 4
      - 5
      - 6
    

    And since you state that you are using json_query, note that there is also a way to flatten in JMESPath, called flatten projection, so you might bake this is your existing query.

    As an example:

    - debug:
        msg: "{{ [ [1,2],[3,4],[5,6] ] | json_query('[]') }}"
    

    Will also yield the expected result.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search