如何在Jsonnet中遍历深层对象并查找返回指定的子对象
Jsonnet 实现代码
local createCopy(gname, rname, kp) = // 第一层遍历顶层键 std.foldl( function(topResult, topLvlKey) // 已找到目标则直接跳过后续遍历 if topResult != null then topResult else local subObj = kp[topLvlKey]; // 第二层遍历次层键 std.foldl( function(subResult, subKey) if subResult != null then subResult else local currentItem = subObj[subKey]; // 筛选类型为PrometheusRule的资源 if currentItem.get("kind", "") != "PrometheusRule" then null else // 遍历规则组匹配组名 std.foldl( function(groupResult, group) if groupResult != null then groupResult else if group["name"] != gname then null else // 遍历组内规则匹配告警名 std.foldl( function(ruleResult, rule) if ruleResult != null then ruleResult else if rule.get("alert", "") == rname then rule else null, group["rules"], null ), currentItem["spec"]["groups"], null ), std.objectFieldsAll(subObj), null ), std.objectFieldsAll(kp), null );
逻辑说明
- Jsonnet是纯声明式语言,没有命令式的循环中断、提前return语法,上述实现通过
std.foldl的累加器传递匹配状态,只要累加器不为null就说明已经找到目标,直接透传跳过后续遍历,模拟了提前返回的效果 - 遍历层级、判断条件完全对齐你编写的伪代码逻辑,未匹配到目标时最终返回null,符合需求要求
测试用例
你可以用以下代码验证功能正确性:
local testKp = { foo: { bar: { kind: "PrometheusRule", spec: { groups: [ { name: "test-group", rules: [ {alert: "TestAlert1", expr: "up == 0"}, {alert: "TargetAlert", expr: "probe_success == 0", for: "5m"}, {alert: "TestAlert2", expr: "cpu_usage > 0.8"} ] }, { name: "other-group", rules: [ {alert: "OtherAlert", expr: "mem_usage > 0.9"} ] } ] } } } }; // 调用后将返回匹配到的TargetAlert规则对象 createCopy("test-group", "TargetAlert", testKp)
内容的提问来源于stack exchange,提问作者Heiko Finzel
相关产品推荐
相关产品推荐

