英文:
Transforming an ansible list of lists to a list of dicts
问题
我终于学会了如何使用 product
创建嵌套列表,但我不喜欢必须通过索引访问结果。product
生成一个列表的列表,而我想要一个字典的列表。
例如,以下代码....
- name: experimenting
hosts: localhost
tasks:
- name: Define some facts
set_fact:
people:
- name: "Fred"
- name: "John"
animals:
- name: "cat"
- debug:
msg: "{{ animals | product(people) }}"
...生成以下输出:
ok: [localhost] => {
"msg": [
[
{
"name": "cat"
},
{
"name": "Fred"
}
],
[
{
"name": "cat"
},
{
"name": "John"
}
]
]
}
我该如何转换它,使其看起来像:
ok: [localhost] => {
"msg": [
{
"animal": {
"name": "cat"
},
"person": {
"name": "Fred"
}
},
{
"animal": {
"name": "cat"
},
"person": {
"name": "John"
}
}
]
}
在C#中,我会使用LINQ的 Select
语句,但我在ansible世界中找不到等效的方法。
英文:
I finally learned how to do nested lists with product
, but I don't like that I have to access the results by indices. product
produces a list of lists, and I want a list of dicts.
For example, the following code....
- name: experimenting
hosts: localhost
tasks:
- name: Define some facts
set_fact:
people:
- name: "Fred"
- name: "John"
animals:
- name: "cat"
- debug:
msg: "{{ animals | product(people) }}"
...produces the following output:
ok: [localhost] => {
"msg": [
[
{
"name": "cat"
},
{
"name": "Fred"
}
],
[
{
"name": "cat"
},
{
"name": "John"
}
]
]
}
How can I transform that so it looks like:
ok: [localhost] => {
"msg": [
{
animal: {
name: "cat"
},
person: {
name: "Fred"
}
},
{
animal: {
name: "cat"
},
person: {
name: "John"
}
}
]
}
In C#, I would use the LINQ Select
statement, but I can't find the equivalent of that in ansible world.
答案1
得分: 1
以下是翻译好的内容:
这个示例没有使用 chatGPT,因为(至少暂时)受到网站规则的限制。此外,它对您最初的问题进行了一些修复,以遵循最佳实践,如仅在需要时使用 set_facts
,以及仅在必要时在任务中进行循环。
这个自解释的剧本带有中间调试,应该很容易理解并提供您期望的结果:
---
- name: 实验
hosts: localhost
gather_facts: false
vars:
people:
- name: "Fred"
- name: "John"
animals:
- name: "cat"
people_as_dict: "{{ ['people: '] | product(people) | map('join') | map('from_yaml') }}"
animals_as_dict: "{{ ['animal: '] | product(animals) | map('join') | map('from_yaml') }}"
people_animals: "{{ people_as_dict | product(animals_as_dict) | map('combine') }}"
tasks:
- name: 将人员列表转换为每个元素都是一个字典
ansible.builtin.debug:
var: people_as_dict
- name: 对动物执行与上述相同的操作
ansible.builtin.debug:
var: animals_as_dict
- name: 组合每个元素以获得预期的结果
ansible.builtin.debug:
var: people_animals
演示运行:
PLAY [实验] ******************************************************************************************************************************************************************************************
TASK [将人员列表转换为每个元素都是一个字典] *********************************************************************************************************************************************************
ok: [localhost] => {
"people_as_dict": [
{
"people": {
"name": "Fred"
}
},
{
"people": {
"name": "John"
}
}
]
}
TASK [对动物执行与上述相同的操作] *****************************************************************************************************************************************************************
ok: [localhost] => {
"animals_as_dict": [
{
"animal": {
"name": "cat"
}
}
]
}
TASK [组合每个元素以获得预期的结果] *****************************************************************************************************************************************************************
ok: [localhost] => {
"people_animals": [
{
"animal": {
"name": "cat"
},
"people": {
"name": "Fred"
}
},
{
"animal": {
"name": "cat"
},
"people": {
"name": "John"
}
}
]
}
PLAY RECAP ******************************************************************************************************************************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
英文:
That one is not written using chatGPT as it is (at least temporarily) forbidden by site rules. Moreover, it includes some fixes on your initial question to respect best practice like using set_facts
only when it is needed and looping in a task only when necessary.
This self explanatory playbook with intermediate debug should be quite easy to get and gives what you expect:
---
- name: experiment
hosts: localhost
gather_facts: false
vars:
people:
- name: "Fred"
- name: "John"
animals:
- name: "cat"
people_as_dict: "{{ ['people: '] | product(people) | map('join') | map('from_yaml') }}"
animals_as_dict: "{{ ['animal: '] | product(animals) | map('join') | map('from_yaml') }}"
people_animals: "{{ people_as_dict | product(animals_as_dict) | map('combine') }}"
tasks:
- name: Tranform people list so that each element is a dict
ansible.builtin.debug:
var: people_as_dict
- name: Do the same thing as above with animals
ansible.builtin.debug:
var: animals_as_dict
- name: combine every element to get expected resutl
ansible.builtin.debug:
var: people_animals
Demo run:
PLAY [experiment] ******************************************************************************************************************************************************************************************
TASK [Tranform people list so that each element is a dict] *************************************************************************************************************************************************
ok: [localhost] => {
"people_as_dict": [
{
"people": {
"name": "Fred"
}
},
{
"people": {
"name": "John"
}
}
]
}
TASK [Do the same thing as above with animals] *************************************************************************************************************************************************************
ok: [localhost] => {
"animals_as_dict": [
{
"animal": {
"name": "cat"
}
}
]
}
TASK [combine every element to get expected resutl] ********************************************************************************************************************************************************
ok: [localhost] => {
"people_animals": [
{
"animal": {
"name": "cat"
},
"people": {
"name": "Fred"
}
},
{
"animal": {
"name": "cat"
},
"people": {
"name": "John"
}
}
]
}
PLAY RECAP *************************************************************************************************************************************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
答案2
得分: -3
我明白了。
- name: 实验
hosts: localhost
tasks:
- name: 定义一些事实
set_fact:
people:
- name: "Fred"
- name: "John"
animals:
- name: "cat"
- name: 转换数据
set_fact:
transformed: "{{ transformed | default([]) + [{'animal': item[0], 'person': item[1] }] }}"
loop: "{{ animals | product(people) }}"
- debug:
msg: "{{ transformed }}"
...生成:
ok: [localhost] => {
"msg": [
{
"animal": {
"name": "cat"
},
"person": {
"name": "Fred"
}
},
{
"animal": {
"name": "cat"
},
"person": {
"name": "John"
}
}
]
}
英文:
I figured it out.
- name: experimenting
hosts: localhost
tasks:
- name: Define some facts
set_fact:
people:
- name: "Fred"
- name: "John"
animals:
- name: "cat"
- name: Transform the data
set_fact:
transformed: "{{ transformed | default([]) + [{'animal': item[0], 'person': item[1] }] }}"
loop: "{{ animals | product(people) }}"
- debug:
msg: "{{ transformed }}"
...produces:
ok: [localhost] => {
"msg": [
{
"animal": {
"name": "cat"
},
"person": {
"name": "Fred"
}
},
{
"animal": {
"name": "cat"
},
"person": {
"name": "John"
}
}
]
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论