扁平化和过滤Ansible中的复杂结构-dict列表的dict [英] Flattening and filtering a complex structure in ansible - dict of list of dict

查看:79
本文介绍了扁平化和过滤Ansible中的复杂结构-dict列表的dict的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以这种方式表示的数据:

I have data that is represented in this manner:

 {
    "key1": [{
      "name": "some name1",
      "index": "some idx1"
    },
    {
      "name": "some name2",
      "index": "some idx2"
    },
    {
      "name": "some name3",
      "index": "some idx3"
    }],
    "key2": [{
      "name": "some name4",
      "index": "some idx4"
    },
    {
      "name": "some name5",
      "index": "some idx5"
    },
    {
      "name": "some name6",
      "index": "some idx6"
    }]
}    

我想将以上内容转换为这个,这基本上是一个字典,具有现有索引列表的键.

I would like to convert the above to this, which is basically a dictionary with the existing key to a list of the indices.

{ 
      "key1": [some idx1, some idx2, some idx3],
      "key2": [some idx4, some idx5, some idx6]
}

我已经看到了一些使用map,extract和Combine的示例,但是还不能完全使用它.但是我可以使用jinja来做到这一点,下面的代码. 我的问题是,实现上述目标的最佳方法是什么.关于此类事情的最佳建议是什么-是否有任何理由为什么不应该使用jinja2进行更复杂的操作(假设我所看到的一个衬板过于复杂,其他人可能很难弄清楚out-因此使脚本难以维护).

I have seen a couple of examples using map, extract and combine, but couldn't quite get it to work as yet. I was however able to do it using jinja, the code is below. My question is, what is the best way to accomplish the above. What is the recommended best practice with regards to this kind of things - is there any reason why more complex operations shouldn't be done using jinja2 (given that the one liners i have seen are overly complex and probably would be difficult for others to figure out - consequently making the script difficult to maintain).

下面是完成此操作的代码,但是同样,不确定执行此操作的最佳方法:

here is the code that does the trick, but again, not sure if the best way of accomplishing this:

- hosts: local
  tags: test1
  gather_facts: False
  vars:
    dict1:
      key1:
        - { name: some name1, index: some idx1 }
        - { name: some name2, index: some idx2 }
        - { name: some name3, index: some idx3 }
      key2:
        - { name: some name4, index: some idx4 }
        - { name: some name5, index: some idx5 }
        - { name: some name6, index: some idx6 }
  tasks:      
  - name: "dict of list of dict"
    set_fact:
      index_map: |
        {% set map = dict() %}
        {% for k,v in dict1.iteritems() %}
          {% set x=map.__setitem__(k, []) %}
          {% for item in v %}
            {% set x= map[k].append(item.name) %}
          {% endfor %}
        {% endfor %}
        {{ map }}
  - debug: 
      msg: "{{ index_map }}"

为了进一步解决这个问题,我试图解决更多问题:给定一个'index',我想找到与之关联的键.我认为,目标结构使我可以更轻松地做到这一点.因此,无论是对索引列表的键的决定,还是对键的索引的决定都足够.

To expand on the problem im trying to solve a bit more: Given an 'index' , i want to find the key it is associated it with. The target structure would allow me to do that a bit easier i think. so either a dict of key to a list of index, or a dict of index to key would suffice.

谢谢您的建议.

推荐答案

Ansible具有非常有限的工具来处理字典中的键(请参阅这个答案).

Ansible has rather limited tools to work with keys in dictionaries (see this answer).

但是 dictsort 过滤器有时会很方便,例如您的情况.
它将dict转换为列表,您可以使用json_query对其进行处理.

But dictsort filter can be handy sometimes, as in your case.
It converts dict into list and you can use json_query to process it.

这是一项通过索引名称获取根密钥的任务:

Here's a task to fetch root key by index name:

- debug:
    msg: "key is '{{ list_with_keys | json_query(qry) }}' for index {{ item }}"
  vars:
    list_with_keys: "{{ dict1 | dictsort | to_json | from_json }}"
    qry: "[?contains(([1] | [].index),`{{ item }}`)][] | [0]"
  with_items:
    - some idx5
    - some idx3

其中dict1来自您的示例.

这篇关于扁平化和过滤Ansible中的复杂结构-dict列表的dict的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆