Jinja 用于在地图中构造字典:[1, 2] 到 [{'x': 1}, {'x': 2}]

Jinja for constructing dictionary in map: [1, 2] into [{'x': 1}, {'x': 2}]

大多数 Jinja 过滤器都是关于减少数据量的。 如果我想把它变大怎么办?

输入

一个列表。这些值可以很简单,也可以很复杂。

- 1
- 'a'
- ['b', 'c']
- {'d': 'e'}

期望的输出

我想生成一个列表。

- x: 1
- x: a
- x: ['b', 'c']
- x: {'d': 'e'}

我要找的是

{{ input | map(some_filter, key='x') | list }}

我可以为 some_filter 使用什么?

备注

我正在为此使用 Ansible。 因此,使用带有 json_query 过滤器的 JMESPath 的解决方案是有效的。 同样,Ansible 的解决方案使用 dict2itemsitems2dict 以某种方式也是有效的。

下面的任务完成工作

    - debug:
        msg: "{{ input|json_query('[*].{x: @}') }}"

给予

  msg:
  - x: 1
  - x: a
  - x:
    - b
    - c
  - x:
      d: e

dict2items is useless here because the input is a list. Also items2dict is useless here because the result shall be a list too. In addition, dict也是没用的,因为它不是过滤器,不能用在map中。没有 json_query 必须使用 loop。例如

    - set_fact:
        output: "{{ output + [{'x': item}] }}"
      loop: "{{ input }}"
      vars:
        output: []

可以写一个过滤器。例如

shell> cat filter_plugins/item2dict.py 
def item2dict(t):
    h = {t[0]:t[1]}
    return h

class FilterModule(object):
    ''' Ansible filters. item2dict'''

    def filters(self):
        return {
            'item2dict': item2dict
            }

那么下面的任务给出了相同的结果

   - debug:
        msg: "{{ 'x'|product(input)|map('item2dict')|list }}"