Home > Blockchain >  Ansible - Create new dict based on matching items in list
Ansible - Create new dict based on matching items in list

Time:11-25

There is a list:

mylist: ['a_value', 'something_else']

There is a dict:

my_dict:
  a_value:
    something: true
  bar:
    foo: false
  something_else:
    placeholder: true

There is an Ansible task to set a fact for a new dict.

- name: "Create a new dict, when name(s) in the list match the key in the dict"
  set_fact:
    new_dict: "{{ new_dict | default({}) | combine({item.key: item.value}) }}"
  loop: 
    - "{{ my_dict | dict2items }}"
    - "{{ my_list }}"
  when: my_list??? item

Q: How would I configure Ansible to create a new dict, when the name(s) match the key in the dict?

In this example, desired output:

new_dict:
  a_value:
    something: true
  something_else:
    placeholder: true

CodePudding user response:

You complicated the task by adding my_list in the loop, creating yourself a list of list and making it more complex that it really was.

So, as a first step, you could corrected your logic and do:

- set_fact:
    new_dict: "{{ new_dict | default({}) | combine({item.key: item.value}) }}"
  loop: "{{ my_dict | dict2items }}"
  when: item.key in my_list
  vars:
    my_list: ['a_value', 'something_else']
    my_dict:
      a_value:
        something: true
      bar:
        foo: false
      something_else:
        placeholder: true

- debug:
    var: new_dict

Which gives:

TASK [set_fact] *************************************************************************
ok: [localhost] => (item={'key': 'a_value', 'value': {'something': True}})
skipping: [localhost] => (item={'key': 'bar', 'value': {'foo': False}}) 
ok: [localhost] => (item={'key': 'something_else', 'value': {'placeholder': True}})

TASK [debug] ****************************************************************************
ok: [localhost] => 
  new_dict:
    a_value:
      something: true
    something_else:
      placeholder: true

This said, there is a way shorter approach, using selectattr.
So, with this one-liner:

- debug:
    var: my_dict | dict2items | selectattr('key', 'in', my_list) | items2dict
  vars:
    my_list: ['a_value', 'something_else']
    my_dict:
      a_value:
        something: true
      bar:
        foo: false
      something_else:
        placeholder: true

We get:

TASK [debug] ****************************************************************************
ok: [localhost] => 
  my_dict | dict2items | selectattr('key', 'in', my_list) | items2dict:
    a_value:
      something: true
    something_else:
      placeholder: true

CodePudding user response:

extract the values of the mylist items from my_dict

  _values: "{{ mylist|map('extract', my_dict) }}"

gives

  _values:
  - something: true
  - placeholder: true

Then create new_dict

  new_dict: "{{ dict(mylist|zip(_values)) }}"

gives

  new_dict:
    a_value:
      something: true
    something_else:
      placeholder: true
  • Related