1073 shaares
607 private links
607 private links
Let's say you have a list of dicts, e.g.,
unison_jobs:
- name: sites
roots:
- "root = {{ ansible_env.HOME }}/sites"
- "root = ssh://luxor/{{ ansible_env.USER }}/sites"
opt: "-auto"
- name: projects
roots:
- "root = {{ ansible_env.HOME }}/projects"
- "root = ssh://luxor/{{ ansible_env.USER }}/projects"
opt: "-auto"
and you want to reference the first root element of the job named projects.
Notice that I want to reference the dicts by its name value and not by its index number (so not simply unison_jobs[n]).
This is not that hard, but enough time passes between occurrences that I forget the specifics and have to look it up again. I hope by writing it down that I will strengthen my ability to recall, or at least give myself a fixed spot to look for it.
{{ unison_jobs | selectattr('name, 'equalto', 'projects') | map(attribute='roots') | first }}
How does map(attribute='somekey') work? Does it return a list even if the referenced key is a non-list item? Yes, by default it always returns a list. Does that mean we can set some option to disable that behaviour? Does not look like it, no.
- https://stackoverflow.com/a/31896249 - Ansible: filter a list by its attributes
- https://jinja.palletsprojects.com/en/stable/templates/#jinja-filters.map - I don't see any option that would force the returned value to be scalar (i.e., not list)
- https://old.reddit.com/r/ansible/comments/pqkom8/jinja_filtering_or_how_i_learned_to_filter - a very nice explainer on how to use Jinja filters such as
select,selectattr, andmap - https://www.middlewareinventory.com/blog/ansible-map
- https://stackoverflow.com/questions/71351075/selectattr-returns-generator-rows-and-cannot-use-results-as-a-dict -
selectattr()returns generator object by default - https://github.com/pallets/jinja/issues/288 -
map()filter returns generator object by default - https://www.ansiblepilot.com/articles/filtering-data-in-ansible-selectattr-and-map