我有两个带有应用程序描述的数组:
source_array:
- status: Active
AppName": "Application 1"
version: "0.1.1"
metadata: ""
- status": "Active"
AppName: "Application 2"
version: "0.2.2"
metadata: "ID123"
- status: "Active"
AppName: "Application 3"
version: "0.3.3"
metadata: ""
并且:
target_array:
- status: "Active"
AppName: "Application 1"
version: "0.1.1"
metadata: ""
- status: "Active"
AppName: "Application 2"
version: "0.2.2"
metadata: "ID321"
- status: "Active",
AppName: "Application 3"
version: "0.3.0"
metadata: ""
我需要根据版本字段比较这两个数组。 因此,例如,所需的结果应该是:
[{
"status": "Active",
"AppName": "Application 3",
"version": "0.3.0",
"metadata": ""
}]
我尝试使用差异过滤器,但它还会返回secondf元素-因为它具有不同的元数据
- name: Comparing arrays
set_fact:
delta: "{{ source_array | difference(target_array) }}"
我得到的结果不正确:
[{
"status": "Active",
"AppName": "Application 2",
"version": "0.2.2",
"metadata": "ID123"
},
{
"status": "Active",
"AppName": "Application 3",
"version": "0.3.3",
"metadata": ""
},
{
"status": "Active",
"AppName": "Application 2",
"version": "0.2.2",
"metadata": "ID321"
},
{
"status": "Active",
"AppName": "Application 3",
"version": "0.3.0",
"metadata": ""
}]
任何帮助将不胜感激!
答案 0 :(得分:0)
这确实不平凡。您没有提供太多上下文,但是我怀疑您想做的事情是检查应用程序是否已经更新或应该更新。是吗?
这是一种方法:
- hosts: localhost
vars:
array1:
- status: "Active"
AppName: "Application 1"
version: "0.1.1"
metadata: ""
- status: "Active"
AppName: "Application 2"
version: "0.2.2"
metadata: "ID321"
- status: "Active"
AppName: "Application 3"
version: "0.3.3"
metadata: ""
array2:
- status: "Active"
AppName: "Application 1"
version: "0.1.1"
metadata: ""
- status: "Active"
AppName: "Application 2"
version: "0.2.2"
metadata: "ID321"
- status: "Active"
AppName: "Application 3"
version: "0.3.0"
metadata: ""
tasks:
- name: "Show matching pattern"
debug:
msg: "{{'^' + (array1|map(attribute='version'))|difference(array2|map(attribute='version'))|join('|') + '$'}}"
- name: "Compare arrays"
debug:
msg: "{{ array1 | selectattr('version', 'match', '^' + (array1|map(attribute='version'))|difference(array2|map(attribute='version'))|join('|') + '$') | list }}"
通过首先找到“较新版本”,然后根据这些版本筛选原始列表来工作。但这是一个脆弱的原因:
array1
中)。也许您应该考虑一个不同的数据结构,例如映射(dict)。请参见下面的current_state
变量:
- hosts: localhost
vars:
current_state:
"Application 1":
status: "Active"
version: "0.1.1"
metadata: ""
"Application 2":
status: "Active"
version: "0.2.2"
metadata: "ID321"
"Application 3":
status: "Active"
version: "0.3.0"
metadata: ""
new_applications:
- status: "Active"
AppName: "Application 1"
version: "0.1.1"
metadata: ""
- status: "Active"
AppName: "Application 2"
version: "0.2.2"
metadata: "ID321"
- status: "Active"
AppName: "Application 3"
version: "0.3.3"
metadata: ""
- status: "Active"
AppName: "Application 4"
version: "0.1.0"
metadata: ""
tasks:
- name: "Different appraoch"
debug:
msg: "{{ item.0 }} -- {{ item.1 }} -- Should update: {{ item.1.version is version((current_state[item.0]|default({'version': '0.0.0'}))['version'], '>') }}"
loop: "{{ new_applications|map(attribute='AppName')|zip(new_applications)|list }}"
- name: "Build 'current_state' from a list (if not available as is)"
# There might be a smarter way using items2dict...
set_fact:
dict_from_list: "{{ dict_from_list|default({})|combine({item[0]: item[1]})}}"
loop: "{{ new_applications|map(attribute='AppName')|zip(new_applications)|list }}"
- debug:
var: dict_from_list
此版本修复了上述两个问题中的最后一个。如果两个数组的顺序不相同,或者数组的长度不相同,它也会更健壮。
我选择忽略的第一个问题,因为尽管您的问题导致相信array1
和array2
是可互换的,但我假设在给定的上下文中它们实际上不是可互换的。