如何反向检查字典 YAML 中的父项

How to reverse check the parent in a dictionary YAML

我有一本与下面结构完全相同的字典。

我在 Ansible 代码中挣扎的地方,我将如何处理用户输入 apple,并且我确定类型是水果?
当用户输入 spinach 时,Ansible 将其识别为 veggie?

基本上,我如何反向检查字典中的父项?编辑:使用 selectattr 后,如何将其分配给一个变量以供将来使用?目前,我得到 food_groups |选择属性('names','contains',食物)| first).type: fruit 作为输出,我如何只将 FRUIT 分配给一个变量?

groups:
   - type: fruit
     names:
     - apple
     - oranges
     - grapes
   - type: veggie
     names:
     - broccoli
     - spinach

您可以为此使用 selectattr and the contains Ansible 测试。

重要说明:不要命名你的字典groups,因为你有与特殊变量冲突的风险一样的名字。这里,我命名为food_groups.

因此,给出食物类型的任务很简单:

- debug:
    var: (food_groups | selectattr('names', 'contains', food) | first).type

假设你要断言的食物在一个变量名里food


鉴于剧本:

- hosts: localhost
  gather_facts: no
  vars_prompt:
    - name: food
      prompt: What food to you want to know the group?
      private: no

  tasks:
    - debug:
        var: (food_groups | selectattr('names', 'contains', food) | first).type
      vars:
        food_groups:
          - type: fruit
            names:
            - apple
            - oranges
            - grapes
          - type: veggie
            names:
            - broccoli
            - spinach

这产生:

What food to you want to know the group?: grapes

PLAY [localhost] *******************************************************************

TASK [debug] ***********************************************************************
ok: [localhost] => 
  (food_groups | selectattr('names', 'contains', food) | first).type: fruit

问:"用户输入 'apple',并且我确定类型是 'fruit'?"

A:创建一个将项目映射到组的字典,例如给定数据

    my_groups:
      - type: fruit
        names:
          - apple
          - oranges
          - grapes
          - tomato
      - type: veggie
        names:
          - broccoli
          - spinach
          - tomato

下面的任务

    - set_fact:
        my_dict: "{{ my_dict|d({'undef': 'undef'})|
                     combine({item.1: [item.0.type]}, list_merge='append') }}"
      with_subelements:
        - "{{ my_groups }}"
        - names

给予

  my_dict:
    apple: [fruit]
    broccoli: [veggie]
    grapes: [fruit]
    oranges: [fruit]
    spinach: [veggie]
    tomato: [fruit, veggie]
    undef: undef

我将 'tomato' 添加到两个组以测试多个组中的成员资格。项目组的标识现在很简单,例如

    - debug:
        msg: "{{ my_item|d('undef') }} is {{ my_dict[my_item|d('undef')]|d('none') }}"

默认给

  msg: undef is undef

当您输入字典中不存在的项目时,您会得到

shell> ansible-playbook playbook.yml -e my_item=foo
...
  msg: foo is none

当您输入字典中的项目时,您会得到组

shell> ansible-playbook playbook.yml -e my_item=spinach
...
  msg: spinach is ['veggie']