REPOST Unable to edit previous question:
I have made a mistake in the instructions... It should be like this, basically need the IPs into array values under "swapped" dict.
The completely first input data is this:
IPs: [ 'ip1', 'ip2', 'ip3' ]
DICT: { 'ip1': 'reg1', 'ip2': 'reg2', 'ip3': 'reg2', 'ip4': 'reg3', ... }
I managed to make 2 lists out of them which I thought would be easier.
list1: {{ DICT | dict2items() | selectattr('key', 'in', IPs) | list | map(attribute='value') | list }}
list2: {{ DICT | dict2items() | selectattr('key', 'in', IPs) | list | map(attribute='key') | list }}
-----
list1: [ 'reg1', 'reg2', 'reg2' ]
list2: [ 'ip1', 'ip2', 'ip3']
I need it condensed into this format
{ 'reg1': 'ip1', 'reg2': [ 'ip2', 'ip3' ] }
or this is also acceptable
{ 'reg1': [ 'ip1' ], 'reg2': [ 'ip2', 'ip3' ] }
This "gives" me what I want, but the moment I make it a dict it just does not condense on its own.
{{ dict(list1 | zip(list2) | list }}
gives
{ 'reg1': 'ip1', 'reg2': 'ip2' }
The closest I've been so far is this but I just don't know how to convert the values back from the key/value list of dict.
{{ dict(dict(list2 | zip(list1)) | dict2items() | groupby(attribute='value') | list ) }}
gets me this \|/
{ 'reg2': [{'key': 'ip2', 'value': 'reg2'}, {'key': 'ip3', 'value': 'reg2'}], 'reg1': [{'key': 'ip1', 'value': 'reg1'}] }
If we have this:
IPs: [ 'ip1', 'ip2' ]
DICT: { 'ip1': 'reg1', 'ip2': 'reg2', 'ip3': 'reg2', 'ip4': 'reg3', ... }
Result should be:
{ 'reg1': [ 'ip1' ], 'reg2': [ 'ip2' ] }
In @Vladimir-Botka's solution the problem is that it's not dynamically creating the arrays. It's simply grabbing whatever is defined in the original DICT.
arr: "{{ DICT|dict2items|groupby('value') }}"
keys: "{{ arr|map('first')|list }}"
vals: "{{ arr|map('last')|map('map', attribute='key')|list }}"
var1: "{{ dict(keys|zip(vals)) }}"
regs: "{{ IPs|map('extract', DICT) }}"
var2: "{{ var1|dict2items|selectattr('key','in', regs)|items2dict }}"
Result is
{ 'reg1': [ 'ip1' ], 'reg2': [ 'ip2' , 'ip3' ] }
If there was another IP defined in reg1, the final variable would reflect that but it's supposed to have only ip1, that is defined in IPs.
IPs: [ip1, ip2, ip3]
DICT: {ip1: reg1, ip2: reg2, ip3: reg2, ip4: reg3}
Use json_query to get the lists of keys. For example,
arr: "{{ DICT|dict2items|groupby('value') }}"
keys: "{{ arr|map('first')|list }}"
vals: "{{ arr|map('last')|map('json_query', '[].key')|list }}"
var1: "{{ dict(keys|zip(vals)) }}"
give
var1:
reg1: [ip1]
reg2: [ip2, ip3]
reg3: [ip4]
Then, select hashes where at least one item of the list is present in IPs
regs: "{{ IPs|map('extract', DICT)|unique }}"
var2: "{{ var1|dict2items|selectattr('key','in', regs)|items2dict }}"
give
var2:
reg1: [ip1]
reg2: [ip2, ip3]
Example of a complete playbook
- hosts: localhost
vars:
IPs: [ip1, ip2, ip3]
DICT: {ip1: reg1, ip2: reg2, ip3: reg2, ip4: reg3}
arr: "{{ DICT|dict2items|groupby('value') }}"
keys: "{{ arr|map('first')|list }}"
vals: "{{ arr|map('last')|map('json_query', '[].key')|list }}"
var1: "{{ dict(keys|zip(vals)) }}"
regs: "{{ IPs|map('extract', DICT)|unique }}"
var2: "{{ var1|dict2items|selectattr('key','in', regs)|items2dict }}"
tasks:
- debug:
var: var1
- debug:
var: var2