Pedro Ribeiro
Pedro Ribeiro

Reputation: 25

Transforming ansible list into a dict of ocurrences

So, I have this Ansible data structure (variable):

variable:
  identifier_1:
    - 1
    - 2
    - 1
    - 1
  identifier_2:
    - 1
    - 2
    - 3

and I need to turn into a dictionary like:

variable:
  indentifier_1:
    - 1: 3
    - 2: 1
  identifier_2:
    - 1: 1
    - 2: 1
    - 3: 1

How can I count the number of occurrences of a certain object in a hash that matches a condition in Ansible?

I've tried to apply the logic that is used in the above link but couldn't translate it to my use case since my list items are simply numbers.

Upvotes: 2

Views: 61

Answers (2)

Frenchy
Frenchy

Reputation: 17007

you could use a custom filter:

you create a folder filter_plugins in your playbook folder (i have named the file myfilters.py and the filter CounterX)

#!/usr/bin/python
class FilterModule(object):
    def filters(self):
        return {
            'CounterX': self.CounterX
        }

    def CounterX(self, obj):
        dicts={}   

        for k in obj.keys():
            mydict = dict((x,obj[k].count(x)) for x in set(obj[k]))
            dicts[k] = mydict

        return dicts

then you use it in your playbook:

- name: vartest
  hosts: localhost
  vars:
    variable:
      identifier_1:
        - 1
        - 2
        - 1
        - 1
      identifier_2:
        - 1
        - 2
        - 3
  tasks:
    - name: transform value
      set_fact:
        result: "{{ variable | CounterX }}"

    - name: display result
      debug:
        var: result

result:

ok: [localhost] => {
    "result": {
        "identifier_1": {
            "1": 3,
            "2": 1
        },
        "identifier_2": {
            "1": 1,
            "2": 1,
            "3": 1
        }
    }
}

Upvotes: 1

Vladimir Botka
Vladimir Botka

Reputation: 68034

For example

    - set_fact:
        f1: "{{ f1|d([]) + [{item: _len|int}] }}"
      loop: "{{ _unq }}"
      vars:
        _lst: "{{ identifier_1 }}"
        _unq: "{{ _lst|unique|sort }}"
        _len: "{{ _lst|select('eq', item)|length }}"

gives

  f1:
  - 1: 3
  - 2: 1

Upvotes: 1

Related Questions