ansible/jinja2 拒绝具有特定属性的字典列表中的所有项目

ansible/jinja2 拒绝具有特定属性的字典列表中的所有项目

我有一系列这样的口述记录:

list_of_dicts:
  - name: Item1
  - name: Item2
    type: special
  - name: Item3
  - name: Item4
    type: small

如您所见,并非所有项目都有type属性。上下文:如果没有type设置属性,则表示该项目属于默认类型。

我想选择所有不属于类型的项目special

我尝试过这个:list_of_dicts | rejectattr('type', 'equalto', 'special')

AnsibleUndefinedVariable: 'dict object' has no attribute 'type'不幸的是,由于某些项目没有类型,因此此操作失败并出现错误。

有什么好方法可以解决这个问题?

答案1

编辑:我实际上没有足够关注@ranjandas 对现有答案的最新编辑以及以下评论。我的第一个解决方案几乎相似。我猜你对第二个更感兴趣。


这里有两种不同的方法可以满足您的要求。

  1. 第一个解决方案仅使用 ansible 中默认可用的过滤器:rejectattr您已经提到的 和它的对应项selectattr。这个想法是添加两个列表。第一个是通过选择所有没有type属性的字典来制作的。第二个是通过选择具有type属性的字典并拒绝那些等于 的字典来制作的special

  2. 对于第二个解决方案,我使用了json_query筛选这需要pip install jmespath控制器。正如您在下面看到的,它更加紧凑。

这是你的选择 !

演示剧本:

---
- name: Show not so special items
  hosts: localhost
  gather_facts: false

  vars:
    list_of_dicts:
      - name: Item1
      - name: Item2
        type: special
      - name: Item3
      - name: Item4
        type: small

  tasks:
    - name: Use select/rejectattr
      debug:
        msg: >-
          {{
            (list_of_dicts | selectattr('type', 'undefined') | list)
            +
            (list_of_dicts | selectattr('type', 'defined') | rejectattr('type', 'eq', 'special') | list)
          }}

    - name: Use json_query
      vars:
        query: "[?type != 'special']"
      debug:
        msg: "{{ list_of_dicts | json_query(query) | list }}"

这使:

PLAY [Show not so special items] **********************************************************************************************************************************************************************************

TASK [Use select/rejectattr] **************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        {
            "name": "Item1"
        },
        {
            "name": "Item3"
        },
        {
            "name": "Item4",
            "type": "small"
        }
    ]
}

TASK [Use json_query] *********************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        {
            "name": "Item1"
        },
        {
            "name": "Item3"
        },
        {
            "name": "Item4",
            "type": "small"
        }
    ]
}

PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

答案2

您应该使用rejectattr来拒绝type未定义的项目并使用selectattr选择特殊的项目equalto

{{ list_of_dicts | rejectattr("type", "undefined") | selectattr("type", "equalto", "special") | list }}

编辑:

如何将下面给出的两个列表合并起来?我不知道这是否是最好的方法,但它确实有效。

{{ list_of_dicts | selectattr("type", "undefined") | list }} + {{ list_of_dicts | rejectattr("type", "undefined") | rejectattr("type", "equalto", "special") | list}}

相关内容