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

查看:40
本文介绍了在 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 }}"

为了扩展我试图解决的问题:给定一个索引",我想找到与其关联的键.我认为目标结构可以让我更容易地做到这一点.所以要么是索引列表的键字典,要么是键索引的字典就足够了.

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 取自您的示例.

where dict1 is taken from your example.

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

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