JSONNET遍历未知键名属性方法及数组合并方案问询
JSONNET 动态遍历未知键并合并数组方案
输入与期望输出
输入(INPUT)
{ "outside": { "entry1": { "t": [ "c1", "c2" ] }, "entry2": { "t": [ "c1", "d1", "d2" ] } }, "outside2": "irrelevant" }
期望输出(OUTPUT)
{ "outside": { "entry1": { "t": [ "c1", "c2", "d1", "d2" ] }, "entry2": { "t": [ "c1", "c2", "d1", "d2" ] } }, "outside2": "irrelevant" }
问题说明
- 核心难点:
outside下的键名不确定(可能是任意名称,比如somethingelse1、entry500),无法硬编码字段名。 - 拆分任务:
- 在JSONNET中遍历未知名称的属性
- 合并每个属性下的
t数组(计划使用std.setUnion)
- 补充场景:需处理条目
t为空数组的情况,每个条目需与默认数组(如["c1","d1","d2"])合并。
解决方案
核心实现:遍历未知键并合并所有t数组
通过std.objectFields获取outside下的所有键名,再用std.foldl遍历这些键,逐个更新每个条目的t数组为所有t数组的并集:
local input = { "outside": { "entry1": { "t": ["c1", "c2"] }, "entry2": { "t": ["c1", "d1", "d2"] } }, "outside2": "irrelevant" }; // 提取所有outside下的t数组,合并为全集 local mergedT = std.setUnionMany(std.map(function(entry) entry.t, std.objectValues(input.outside))); input { outside: std.foldl( function(result, key) result + { [key]: { t: mergedT } }, std.objectFields(input.outside), {} ) }
补充场景:与默认数组合并(含空数组处理)
如果需要固定和默认数组合并,直接将mergedT替换为默认数组与当前条目t的并集即可,空数组场景也能正常处理:
local defaultT = ["c1", "d1", "d2"]; local input = { "outside": { "entry1": { "t": ["c1", "c2"] }, "entry2": { "t": [] } // 空数组场景 }, "outside2": "irrelevant" }; input { outside: std.foldl( function(result, key) result + { [key]: { t: std.setUnion(input.outside[key].t, defaultT) } }, std.objectFields(input.outside), {} ) }
关键函数说明
std.objectFields(obj):返回对象的所有键名数组,解决未知键遍历问题std.setUnion(arr1, arr2):返回两个数组的并集,自动去重std.setUnionMany(arrList):返回多个数组的并集,适合合并所有条目t的场景std.foldl(func, arr, init):遍历数组,逐步构建新对象,实现批量更新
内容的提问来源于stack exchange,提问作者Andres
相关产品推荐
相关产品推荐

