Reputation: 1307
apologies for the awkward title, but i couldn't figure out a better way to phrase what seems like a very common operation:
i have a list like
repos:
- nrser/x
- nrser/y
and want to transform it to a dict like
repos_dict:
nrser/x: nrser_x
nrser/y: nrser_y
this is super simple in python
repos = ['nrser/x', 'nrser/y']
repos_dict = dict((repo, repo.replace('/', '_')) for repo in repos)
# => {'nrser/x': 'nrser_x', 'nrser/y': 'nrser_y'}
but i can't figure out how to accomplish it with Ansible / Jinja2 (short of dropping into python via a module or plugin, but that seems ridiculous for such a basic use case).
it's easy to map the repos
to a new list with the underscored names (i need to use them in file paths)
set_fact:
repo_filename_segments: "{{ repos | map('replace', '/', '_') | list }}"
but then i need zip them together, and i can't find support for that either (see ziplist1-list2-in-jinja2 and how-to-combine-two-lists-together)
i've tried:
- set_fact:
repos:
- beiarea/www
- beiarea/relib
- set_fact:
repos_dict: {}
- with_items: "{{ repos }}"
set_fact:
"repos_dict[{{ item }}]: "{{ item | replace('/', '_') }}"
but that doesn't work either.
maybe it's not possible in Ansible / Jinja, but it seems like a really elementary operation to have been overlooked.
thanks for any solutions or suggestions.
Upvotes: 5
Views: 7500
Reputation: 31691
Ansible 2.3 adds (amongst others) a zip filter:
- set_fact:
repos:
- beiarea/www
- beiarea/relib
- set_fact:
dirnames: "{{ repos | zip(repos|map('replace', '/', '_')) | list }}"
- debug: var=dirnames
# "dirnames": [
# [
# "beiarea/www",
# "beiarea_www"
# ],
# [
# "beiarea/relib",
# "beiarea_relib"
# ]
# ]
- debug:
msg: "{{ item[0] }} => {{ item[1] }}"
with_items:
- "{{ dirnames }}" # with_items flattens the first level
I'm still looking for a good way to turn that into a dictionary, for easy lookups.
Upvotes: 3