如何通过ytt自定义匹配逻辑合并数组并去除重复项?
问题描述
我有两份YAML文档:
第一份:
--- resources: - index: 1 - index: 2
第二份:
resources: - index: 2 - index: 3 - index: 4
期望合并后的输出是去重后的数组:
resources: - index: 1 - index: 2 - index: 3 - index: 4
我尝试了以下两段ytt代码,但都不生效:
第一段:
#@ load("@ytt:overlay", "overlay") #@ load("@ytt:data", "data") #@overlay/match by=overlay.all, expects="1+" --- resources: #@overlay/match by=lambda idx,left,right: data.values.left[idx]==data.values.right[idx], missing_ok=True #@overlay/replace - index: 1 - index: 2
第二段:
#@ load("@ytt:overlay", "overlay") #@ load("@ytt:data", "data") #@overlay/match by=overlay.all, expects="1+" --- resources: #@overlay/match by=lambda idx,left,right: data.values.left[idx]==data.values.right[idx], missing_ok=True #@overlay/replace - index: 2 - index: 3 - index: 3
请问该如何利用数组值实现ytt的匹配逻辑,完成数组的去重合并?
解决方案
要实现基于index值的数组去重合并,你可以通过以下两种方式实现:
方式一:使用overlay原生匹配+合并逻辑
核心思路是匹配数组中元素的index字段,保留已存在的元素,追加不存在的元素。编写单份overlay文件即可处理:
#@ load("@ytt:overlay", "overlay") #@overlay/match by=overlay.all, expects="1+" --- resources: #@ 匹配两边index相同的元素,允许某一侧不存在该元素 #@overlay/match by=lambda left, right: left["index"] == right["index"], missing_ok=True #@overlay/keep - {} #@ 将一侧独有的元素追加到数组末尾 #@overlay/append #@overlay/match by=lambda left, right: left["index"] != right["index"], missing_ok=True
这段代码的逻辑拆分:
#@overlay/match by=lambda left, right: left["index"] == right["index"]:以index值为依据匹配两个文档中的元素#@overlay/keep:保留匹配到的重复元素,避免重复添加#@overlay/append:将未匹配到的(即index不重复的)元素追加到数组中
方式二:自定义合并去重函数
如果需要更灵活的逻辑控制,可以先合并两个数组再手动去重:
#@ load("@ytt:data", "data") #@ load("@ytt:overlay", "overlay") #@def merge_and_deduplicate(arr1, arr2): #@ seen_indexes = set() #@ result = [] #@ # 遍历合并后的数组 #@ for item in arr1 + arr2: #@ idx = item["index"] #@ if idx not in seen_indexes: #@ seen_indexes.add(idx) #@ result.append(item) #@ return result #@end #@overlay/match by=overlay.all, expects="1+" --- resources: #@ merge_and_deduplicate(data.values.first.resources, data.values.second.resources)
使用这种方式需要将两份原始文档作为数据传入,执行ytt命令时可以这样指定:
ytt -f overlay.yaml --data-value-file first=doc1.yaml --data-value-file second=doc2.yaml
原代码失效原因
你之前的代码存在两个关键问题:
- 匹配函数参数错误:ytt数组匹配的lambda函数参数是两侧的元素(
left和right),而非索引idx,你的逻辑误将索引作为参数处理 - 替换逻辑错误:
#@overlay/replace会直接覆盖整个数组,而非合并元素,导致后执行的overlay会完全覆盖之前的结果
内容的提问来源于stack exchange,提问作者Rakesh Adhikesavan
相关产品推荐
相关产品推荐

