JS实现:检测深层对象中指定键并替换其值
实现
obtainModeSets 函数的方案 先修正示例中的语法问题
你的示例代码里modeSets数组的对象缺少逗号,先修正为可运行的格式:
var obj = { "id": 1, "component": "Preset 1", "priority": 1, "header": { "modeSet": 2 } }; const modeSets = [ { "id": 1, "name": "Mode Set 1" }, { "id": 2, "name": "Mode Set 2" } ];
核心实现思路
- 递归遍历目标对象的所有层级,定位到名为
modeSet的键 - 提前将
modeSets数组转换为以id为键的映射表,提升匹配效率 - 将
modeSet的数值ID替换为映射表中对应的完整对象
完整代码实现
// 构建modeSet映射表,O(1)时间查找匹配项 const modeSetMap = modeSets.reduce((map, item) => { map[item.id] = item; return map; }, {}); function obtainModeSets(targetObj) { // 遍历当前对象的所有自有属性 for (const key in targetObj) { if (Object.prototype.hasOwnProperty.call(targetObj, key)) { const value = targetObj[key]; // 若当前值是对象(非null),递归处理深层结构 if (typeof value === 'object' && value !== null) { obtainModeSets(value); } // 找到modeSet键时替换值 if (key === 'modeSet') { // 找不到匹配项时保留原ID,避免出现undefined targetObj[key] = modeSetMap[value] || value; } } } return targetObj; } // 执行函数 obtainModeSets(obj); console.log(obj.header.modeSet); // 输出结果:{ id: 2, name: 'Mode Set 2' }
关键细节说明
- 映射表优化:使用
reduce将数组转为键值对映射,避免每次匹配都遍历数组,数据量大时性能提升明显 - 递归遍历:支持任意层级的嵌套对象,不管
modeSet在多少层下都能被定位到 - 边界处理:排除
null的情况(因为typeof null会返回'object'),同时处理找不到匹配ID的场景,保留原数值 - 原对象修改:上述实现直接修改传入的对象,如果需要保留原对象不变,可以改用深拷贝的方式:
function obtainModeSets(targetObj) { // 深拷贝原对象,避免修改原始数据 const newObj = JSON.parse(JSON.stringify(targetObj)); const traverse = (obj) => { for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { const value = obj[key]; if (typeof value === 'object' && value !== null) { traverse(value); } if (key === 'modeSet') { obj[key] = modeSetMap[value] || value; } } } }; traverse(newObj); return newObj; } // 执行后原obj不受影响,返回新的修改后对象 const updatedObj = obtainModeSets(obj);
扩展优化
如果需要支持自定义目标键名(比如不止处理modeSet),可以给函数增加参数:
function obtainModeSets(targetObj, targetKey = 'modeSet') { const modeSetMap = modeSets.reduce((map, item) => { map[item.id] = item; return map; }, {}); const traverse = (obj) => { for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { const value = obj[key]; if (typeof value === 'object' && value !== null) { traverse(value); } if (key === targetKey) { obj[key] = modeSetMap[value] || value; } } } }; const newObj = JSON.parse(JSON.stringify(targetObj)); traverse(newObj); return newObj; } // 调用示例:处理名为'customMode'的键 const result = obtainModeSets(obj, 'customMode');
内容的提问来源于stack exchange,提问作者mellows
相关产品推荐
相关产品推荐

