多层JSON结构下表单值与键的通配符匹配优化方案
问题背景与需求
我正在开发网页表单,尝试用以下JSON结构来修改/填充表单:
{ "REGION1": { "CODE1": { "mandatory": 1, "labelId": "labelId", "disableSearch": 1, "dropdownId": "dropdownId", "options": ["opt1", "opt2", "opt3"] } }, "*": { "CODE1": { "mandatory": 0, "labelId": "label2Id", "disableSearch": 1, "dropdownId": "dropdown2Id", "options": ["opt1", "opt2", "opt4"] } } }
比如用户从下拉菜单选择"REGION1"和"CODE1"时,可以这样取值:
var values = myJson[regionText][codeText] // 从下拉框获取的regionText和codeText
需求是:如果regionText没有对应映射,但codeText存在,就匹配通配符"*"对应的取值。因为JSON有5层结构,不想用多层if嵌套,目前用循环匹配的伪代码:
foreach(key in values.keys()) { if(values[regionText]=="REGION2" or values[regionText]=="*") { foreach(key2 in values[key].keys()) { // 继续后续逻辑 } } }
但现有方案在搜索"REGION1"和"CODE2"时失效,需要实现的逻辑是:先查找REGION1下的CODE2,如果不存在,再查找"*"区域下的CODE2。比如下面这个场景:
{ "REGION1": { "CODE1": { "isMandatory": 1, "labelId": "id", "disableSearch": 1, "dropdownId": "id", "stakeholders": ["opt1", "opt2"] } }, "*": { "CODE2": { "isMandatory": 1, "labelId": "id", "disableSearch": 1, "dropdownId": "id", "stakeholders": ["opt1", "opt2"] } } }
最优实现方案
可以写一个通用的取值函数,优先匹配指定区域的目标code,不存在则 fallback 到通配符区域,避免多层嵌套和循环遍历:
function getFormConfig(region, code, config) { // 先检查指定region下是否有目标code if (config[region] && config[region][code]) { return config[region][code]; } // 没有的话检查通配符区域的目标code if (config["*"] && config["*"][code]) { return config["*"][code]; } // 都不存在的话返回null或默认配置 return null; }
函数说明
- 直接通过属性访问而非循环,性能更优,尤其适合多层结构
- 逻辑清晰:先精确匹配
region+code,再匹配通配符区域的code - 可扩展:如果后续需要更多匹配规则(比如多个通配符或层级匹配),可以在函数内补充逻辑,不影响原有结构
调用示例
const myJson = { /* 你的配置JSON */ }; const regionText = "REGION1"; const codeText = "CODE2"; const config = getFormConfig(regionText, codeText, myJson); if (config) { // 用config填充表单:设置label、下拉选项、必填状态等 document.getElementById(config.labelId).textContent = "对应标签"; // ...其他表单操作 }
如果是5层结构,只需要扩展函数的参数和访问层级即可,利用可选链操作符?.避免多层存在性判断,代码更简洁:
function getDeepConfig(level1, level2, level3, level4, level5, config) { // 精确匹配路径 if (config[level1]?.[level2]?.[level3]?.[level4]?.[level5]) { return config[level1][level2][level3][level4][level5]; } // 通配符匹配(假设level1是区域层级,用*替代) if (config["*"]?.[level2]?.[level3]?.[level4]?.[level5]) { return config["*"][level2][level3][level4][level5]; } return null; }
内容的提问来源于stack exchange,提问作者Josh Brown
相关产品推荐
相关产品推荐

