You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用jq遍历JSON规则并将数字引用替换为对应名称?

问题:将智能家居规则中的数字引用替换为对应名称

我通过单次API调用获取到了包含灯光、群组、规则、传感器的完整JSON数据(简化后如下):

{
    "lights": {
        "8": {
            "name": "Room 1 Main"
        }
    },
    "groups": {
        "1": {
            "name": "Room 1",
            "lights": [
                "8",
                "9",
                "10",
                "11",
                "12"
            ]
        }
    },
    "rules": {
        "1": {
            "name": "Light  ON",
            "conditions": [{
                    "address": "/sensors/9/state/presence",
                    "operator": "eq",
                    "value": "true"
                },
                {
                    "address": "/sensors/10/state/lightlevel",
                    "operator": "lt",
                    "value": "12000"
                }
            ],
            "actions": [{
                "address": "/lights/8/state",
                "method": "PUT",
                "body": {
                    "on": true
                }
            }]
        }
    },
    "sensors": {
        "9": {
            "name": "Room 1 Motion"
        },
        "10": {
            "name": "Room 1 Lux"
        }
    }
}

规则中的conditions和actions字段通过地址字符串引用了sensors、lights或groups的ID,我需要将这些数字ID替换为对应对象的name值,生成易读的规则格式,示例输出如下:

{
    "name": "Light ON",
    "conditions": ["Room 1 Motion eq true",
        "Room 1 Lux lt 12000"
    ],
    "actions": "Room 1 Main on true"
}

补充说明:动作的body字段可能包含on、flag(取值为true/false)或status(取值为enabled/disabled)。

请问如何遍历每个规则及其下的条件与动作,完成上述替换?


解决方案

核心思路

  • 解析地址字符串:从address中提取资源类型(如sensors、lights、groups)和对应的ID;
  • 建立名称映射:利用API返回的sensors、lights、groups数据,创建ID到名称的映射表;
  • 遍历处理规则:逐个处理每个规则的条件和动作,替换ID为名称并格式化字符串。

代码实现示例(JavaScript)

// 假设apiData是API返回的完整JSON数据
const apiData = { /* 你的API返回数据 */ };

// 构建ID到名称的映射表
const nameMap = {
    sensors: Object.fromEntries(Object.entries(apiData.sensors).map(([id, item]) => [id, item.name])),
    lights: Object.fromEntries(Object.entries(apiData.lights).map(([id, item]) => [id, item.name])),
    groups: Object.fromEntries(Object.entries(apiData.groups).map(([id, item]) => [id, item.name]))
};

// 从地址中解析对应资源的名称
function getNameFromAddress(address) {
    const parts = address.split('/');
    const type = parts[1];
    const id = parts[2];
    // 容错:如果找不到对应名称,返回标识文本
    return nameMap[type]?.[id] || `Unknown ${type} ${id}`;
}

// 处理单个规则
function processRule(rule) {
    // 格式化条件数组
    const conditions = rule.conditions.map(cond => {
        const resourceName = getNameFromAddress(cond.address);
        return `${resourceName} ${cond.operator} ${cond.value}`;
    });

    // 格式化动作(支持多个动作拼接)
    const actions = rule.actions.map(action => {
        const resourceName = getNameFromAddress(action.address);
        // 提取body中的配置项(适配on/flag/status)
        const [configKey, configValue] = Object.entries(action.body)[0];
        return `${resourceName} ${configKey} ${configValue}`;
    }).join(', ');

    return {
        name: rule.name.trim(),
        conditions,
        actions
    };
}

// 批量处理所有规则
const processedRules = Object.values(apiData.rules).map(processRule);

// 输出结果
console.log(JSON.stringify(processedRules, null, 2));

关键细节说明

  • 地址解析:通过split('/')拆分地址字符串,稳定提取资源类型和ID,适配三种资源类型;
  • 映射表优化:用Object.fromEntries快速转换原数据结构,后续查询名称的时间复杂度为O(1);
  • 动作适配:通过Object.entries动态获取body中的配置项,无需硬编码判断on/flag/status;
  • 容错处理:遇到未知资源或ID时返回标识文本,避免程序中断。

内容的提问来源于stack exchange,提问作者Lorccan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 17:23:20