如何使用Ruby解析嵌套JSON并实现多响应数据关联合并
Ruby解析嵌套JSON并实现设备指令匹配实现方案
1. 依赖说明
Ruby标准库自带json模块可直接完成JSON解析,无需额外安装第三方依赖,Ruby 2.3及以上版本支持Hash#dig方法可以更方便地提取嵌套字段。
2. 核心实现步骤
2.1 解析设备JSON并构建索引表
先把接口返回的设备JSON解析为Ruby哈希,再以设备_id为键构建索引映射,提取所需字段存储:
require 'json' # 解析设备接口返回的JSON字符串,多页响应可直接拼接devices数组 device_resp = JSON.parse(File.read('device_response.json')) devices = device_resp.dig('result', 'devices') || [] # 构建设备索引表:key为设备_id,value为设备核心信息 device_index = devices.each_with_object({}) do |dev, idx| idx[dev['_id']] = { name: dev['name'], type: dev['type'], category: dev['category'], manufacturer: dev.dig('info', 'manufacturer'), reachable: dev['reachable'] } end # 额外构建按设备类型分组的列表,方便后续按编号匹配 device_by_type = devices.group_by { |d| d['category'] }.transform_values { |list| list.sort_by { |d| d['name'] } }
2.2 解析功能列表JSON并合并关联
功能列表JSON结构和设备一致,仅根节点键为items,同样构建索引后关联到对应设备即可:
# 解析功能接口返回的JSON字符串,多页响应可直接拼接items数组 capability_resp = JSON.parse(File.read('capability_response.json')) capabilities = capability_resp.dig('result', 'items') || [] # 构建功能索引,假设功能条目包含device_id字段关联对应设备,可按实际接口字段调整 capabilities.each do |cap| # 把功能关联到对应设备的信息里 next unless device_index.key?(cap['deviceId']) device_index[cap['deviceId']][:capabilities] ||= [] device_index[cap['deviceId']][:capabilities] << cap.slice('_id', 'name', 'description') end
2.3 指令匹配逻辑实现
针对unlock door lock 1这类输入指令,按如下逻辑匹配:
- 提取指令动作(如unlock)、设备类型(如door_lock)、设备编号(如1,编号从1开始对应数组下标0)
- 从按类型分组的设备列表中取出对应编号的设备,获得设备
_id - 从该设备关联的功能列表中匹配动作对应的功能
_id
示例代码:
def parse_command(input, device_by_type, device_index) # 匹配规则可根据实际指令格式调整正则 match = input.match(/^(\w+)\s+(.+?)\s+(\d+)$/) return nil unless match action, type_name, num = match.captures # 把类型名转成下划线格式和category字段匹配 type_key = type_name.gsub(' ', '_') target_devs = device_by_type[type_key] return nil unless target_devs && num.to_i <= target_devs.size target_dev = target_devs[num.to_i - 1] # 匹配对应动作的功能id target_cap = device_index.dig(target_dev['_id'], :capabilities)&.find { |c| c['name'].downcase == action.downcase } return nil unless target_cap { device_id: target_dev['_id'], capability_id: target_cap['_id'], device_name: target_dev['name'], action: action } end # 测试调用 result = parse_command("unlock door lock 1", device_by_type, device_index) # 返回结构示例:{device_id: "1234567897786211fd31f3ed", capability_id: "xxx", device_name: "Front Door", action: "unlock"}
3. 注意事项
- 若功能条目和设备的关联规则不是
deviceId字段,可根据实际接口返回字段调整关联逻辑 - 指令匹配的正则可根据实际输入规则灵活调整,支持更多指令格式
- 若需要合并多页的设备/功能响应,可在解析阶段把多页返回的数组拼接后再构建索引
内容的提问来源于stack exchange,提问作者M2AV
相关产品推荐
相关产品推荐

