JavaScript递归遍历嵌套数组搜索元素时代码异常如何修复
问题说明
实现无限嵌套结构的搜索功能:输入搜索关键词,返回所有层级中title字段包含关键词的元素组成的数组。最初采用递归逻辑编写代码,但运行结果不符合预期,无法定位错误。
测试数据与原有问题代码如下:
const newList = [ { role: "role111", title: "title1", }, { role: "role222", title: "title2", }, { role: "role333", title: "title3", }, { role: "role444", title: "title4", items: [{ role: "role555", title: "title5", }, { role: "role666", title: "title6", }, { role: "role777", title: "title7", items: [{ role: "role888", title: "title888", },{ role: "role8888", title: "title8888", },] },] }, { role: "role999", title: "title999", }, ]; const text = "role888"; const testFunction = ( list, text, emptyArray ) => { let arrayForRender = emptyArray; return list?.filter((item) => { if (item.title.toLowerCase().includes(text.toLowerCase())) { arrayForRender = [...arrayForRender, item]; return arrayForRender; } if (item.items && item.items?.length > 0) { testFunction(item.items, text, arrayForRender); } }); }; console.log(testFunction(newList, text, []));
附言:非常抱歉,我最初的问题表述有误,原问题已不再适用。但仍然感谢所有已经给出建议、以及即将指导我正确掌握递归用法的各位。
错误点梳理
- 对
Array.filter的用法理解错误:filter的回调函数需要返回布尔值,用来判定当前遍历项是否要保留在返回的新数组中。原代码在匹配时返回数组对象(属于真值),会导致所有遍历到的顶层元素不管是否匹配都被保留,最终返回的是顶层数组的错误子集,而非收集到的所有匹配项。 - 递归调用的返回值未被接收:处理子节点
items时调用了递归函数,但没有接收递归返回的结果,深层节点匹配到的内容完全没有被累计到最终结果中。 - 结果累计逻辑失效:原代码通过参数传入初始空数组存储结果,但每次匹配时用展开运算符创建新数组赋值给局部变量
arrayForRender,子递归中创建的新数组无法同步到父级作用域,深层匹配的元素不会被存入最终的结果数组。
修复方案
放弃用filter做跨层级结果收集,改用遍历+递归结果合并的逻辑,每层递归维护自己的结果数组,将子节点递归得到的匹配结果直接合并到当前层结果中即可:
const testFunction = (list, text) => { const result = []; // 非数组场景直接返回空结果兜底 if (!Array.isArray(list)) return result; const keyword = text.toLowerCase(); for (const item of list) { // 当前节点匹配则加入结果 if (typeof item.title === 'string' && item.title.toLowerCase().includes(keyword)) { result.push(item); } // 存在子节点则递归搜索,将子节点匹配结果合并到当前结果 if (Array.isArray(item.items) && item.items.length) { result.push(...testFunction(item.items, text)); } } return result; }; // 测试 console.log(testFunction(newList, text)); // 输出:[{role: 'role888', title: 'title888'}, {role: 'role8888', title: 'title8888'}]
逻辑说明
- 不需要额外传入初始空数组参数,避免参数传递带来的作用域同步问题。
- 增加了类型判断兜底,避免字段不存在、值类型不符合预期时抛出运行时错误。
- 递归逻辑清晰:当前层匹配项直接存入结果,子层所有匹配项通过递归获取后合并,不管嵌套多少层都能正确收集所有匹配元素。
内容的提问来源于stack exchange,提问作者user18119766
相关产品推荐
相关产品推荐

