如何用原生JavaScript遍历嵌套JSON并返回匹配键值的对象
问题:遍历嵌套JSON对象查找指定键值对的对象
我有一个包含嵌套对象和数组的复杂JSON,示例如下:
[ { "Id": 1, "Name": "Foo", "Cached": true, "Accessories": [2, 4, 16], "Promo": [{"Type": 1, "Date": "null", "Priority": 1}, ...], ... }, { "Id": 2, "Name": "Bar", "Cached": false, "Accessories": [16, 32, 64], "Promo": [{"Type": 2, "Date": "null", "Priority": 2}, ...], ... }, ... ]
我需要用JavaScript原生特性(不依赖第三方库)遍历所有层级的键(包括嵌套对象和数组中的),找到匹配指定键值对(比如"Name" = "Bar")的对象并返回。假设该键值对是唯一的,返回首个匹配结果即可。
我试过多个递归函数都没实现预期效果,自己写的最优代码也仍无法正常工作:
function loopThroughJSON(obj, searchKey, searchValue) { if (typeof obj === 'string') { obj = JSON.parse(obj); } for (var key in obj) { if (typeof obj[key] === 'object') { if (Array.isArray(obj[key])) { for (var i = 0; i < obj[key].length; i++) { return loopThroughJSON(obj[key][i], searchKey, searchValue); } } else { return loopThroughJSON(obj[key], searchKey, searchValue); } } else { if ((key === searchKey) && (obj[key] === searchValue)) { return obj; } } } return null; }
解决方案
你的代码存在几个关键问题:
- 遍历数组时,递归第一个元素就直接
return,不管是否找到匹配,导致后续元素完全没机会被检查 - 递归嵌套对象时,同样直接
return递归结果,没判断是否找到匹配,会错过当前对象其他属性的遍历 - 没有排除
null的情况(typeof null === 'object'),会导致不必要的递归
以下是修正后的代码:
function findMatchingObject(obj, searchKey, searchValue) { // 处理传入JSON字符串的情况 if (typeof obj === 'string') { obj = JSON.parse(obj); } // 先检查当前对象是否符合匹配条件 if (typeof obj === 'object' && obj !== null) { if (obj[searchKey] === searchValue) { return obj; } // 遍历当前对象的所有属性 for (const key in obj) { const value = obj[key]; let matchResult; // 如果是数组,逐个元素递归查找 if (Array.isArray(value)) { for (const item of value) { matchResult = findMatchingObject(item, searchKey, searchValue); // 找到匹配就立即返回 if (matchResult) return matchResult; } } // 如果是非数组的对象,递归查找 else if (typeof value === 'object' && value !== null) { matchResult = findMatchingObject(value, searchKey, searchValue); if (matchResult) return matchResult; } } } // 未找到匹配对象 return null; }
关键修正说明:
- 优先检查当前对象是否满足匹配条件,避免漏过当前层级的目标对象
- 遍历数组时,只有当递归找到匹配结果才
return,否则继续遍历下一个元素 - 递归嵌套对象时,先判断递归返回值是否存在,存在才返回,否则继续遍历当前对象的其他属性
- 增加了
null判断,避免对null进行无效递归
测试示例:
假设你有如下数据:
const testData = [ { "Id": 1, "Name": "Foo", "Cached": true, "Accessories": [2, 4, 16], "Promo": [{"Type": 1, "Date": "null", "Priority": 1}] }, { "Id": 2, "Name": "Bar", "Cached": false, "Accessories": [16, 32, 64], "Promo": [{"Type": 2, "Date": "null", "Priority": 2}] } ]; // 查找Name为Bar的对象 const result = findMatchingObject(testData, 'Name', 'Bar'); console.log(result); // 输出Id为2的完整对象
内容的提问来源于stack exchange,提问作者ihorc
相关产品推荐
相关产品推荐

