'Unique Filter of List in Jinja2

I have the following YAML structure:

bri:
  cards:
    - slot: "1"
      subslot: "0"
      ports: 2
    - slot: "1"
      subslot: "1"
      ports: 2
    - slot: "1"
      subslot: "2"
      ports: 2
    - slot: "2"
      subslot: "0"
      ports: 2
    - slot: "2"
      subslot: "1"
      ports: 2

I am attempting to use Jinja2 to get a unique list of slots, i.e.:

['1', '2']

So far, I've managed to apply the following:

{{ bri.cards|map(attribute='slot')|list }}

Which gives me:

['1', '1', '1', '2', '2']

However, I don't seem to be able to find a way to get a unique list.

Ansible

Ansible appears to have a "unique" filter that can do this. But I'm not using Ansible in this case.

My question

Can anyone suggest the best way to achieve this? Should (or can) this be done natively with Jinja2, or should I adopt an alternative approach?



Solution 1:[1]

You can do something like this (depends on how you parse the .yaml file - is it a list of dicts of dicts?):

{% set slots = [] %}
{% for slot in bri.cards if slot not in slots %}
    {% do slots.append(slot) %}
{% endfor %}

Solution 2:[2]

Edited - I did not see the bit about not being able to use the unique filter. For those that can use the unique filter you can do it this way

{{ bri.cards|map(attribute='slot')|unique|list }}

Solution 3:[3]

Similar to above by doru with the append functions, but I noticed Ansible doesn't load the 'do' module for Jinja2, working around that is possible as such: {{ bucket.append(client.client_id) }}

{% set slots = [] %}
{% for slot in bri.cards if slot not in slots %}
    {{ slots.append(slot) }}
{% endfor %}

So using {{}} syntax, you can still issue the append function call, and not have Ansible throw Jinja syntax errors.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 doru
Solution 2
Solution 3 jorr-el