面试题:如何实现findPath函数以获取代码片段指定输出?
实现findPath函数:解决嵌套对象/数组的路径查找问题
嘿,我之前面试也碰到过几乎一样的题!这个需求核心就是遍历嵌套的对象或数组,记录下能找到目标值(或目标键)的完整访问路径。我来一步步给你拆解实现思路和代码:
先明确需求场景
通常这类题的要求是:给定一个嵌套的对象/数组,以及要查找的目标值(或目标键),findPath函数要返回所有从根节点到目标节点的路径字符串,比如a.b.c或者e[2].f这种符合JS访问语法的格式。
核心实现思路
我们用递归遍历的方式来处理嵌套结构,逻辑很清晰:
- 区分对象和数组两种结构:对象遍历键名,数组遍历索引
- 每走一步就记录当前的路径片段
- 当遇到目标值(或键)时,把当前拼接好的路径存入结果列表
- 如果当前节点还是嵌套的对象/数组,就递归遍历它的子节点
完整代码实现(按值查找)
先写最常见的“查找所有值等于目标值的路径”版本:
function findPath(obj, target, currentPath = [], result = []) { // 处理数组:遍历每个索引 if (Array.isArray(obj)) { obj.forEach((item, index) => { // 拼接数组的路径片段,比如 [2] const newPath = [...currentPath, `[${index}]`]; // 找到目标值,把完整路径加入结果 if (item === target) { result.push(newPath.join('')); } // 如果子节点是对象/数组,继续递归遍历 if (typeof item === 'object' && item !== null) { findPath(item, target, newPath, result); } }); return result; } // 处理对象:遍历每个键 if (typeof obj === 'object' && obj !== null) { Object.entries(obj).forEach(([key, value]) => { // 根节点的键不用加.,子节点的键要加.,比如 .b const newPath = [...currentPath, currentPath.length ? `.${key}` : key]; if (value === target) { result.push(newPath.join('')); } // 递归处理子结构 if (typeof value === 'object' && value !== null) { findPath(value, target, newPath, result); } }); return result; } // 非对象/数组的普通值,直接返回结果 return result; }
测试一下效果
用这个测试对象来验证:
const testObj = { a: { b: { c: '面试目标值' }, d: '普通值' }, e: [100, { f: '面试目标值' }, ['嵌套数组', '面试目标值']] }; console.log(findPath(testObj, '面试目标值')); // 预期输出:["a.b.c", "e[1].f", "e[2][1]"]
扩展:按键查找路径
如果你的需求是找所有键等于目标键的路径,只需要修改判断条件就行:
function findPathByKey(obj, targetKey, currentPath = [], result = []) { if (Array.isArray(obj)) { obj.forEach((item, index) => { const newPath = [...currentPath, `[${index}]`]; // 如果要找数组的索引,就判断index是否等于targetKey if (index == targetKey) { result.push(newPath.join('')); } if (typeof item === 'object' && item !== null) { findPathByKey(item, targetKey, newPath, result); } }); return result; } if (typeof obj === 'object' && obj !== null) { Object.entries(obj).forEach(([key, value]) => { const newPath = [...currentPath, currentPath.length ? `.${key}` : key]; // 判断键是否匹配目标 if (key === targetKey) { result.push(newPath.join('')); } if (typeof value === 'object' && value !== null) { findPathByKey(value, targetKey, newPath, result); } }); return result; } return result; }
几个关键注意点
- 一定要处理
null:因为typeof null === 'object',不排除的话会触发错误的递归 - 路径格式的细节:根节点的键不用加
.,数组用[索引]的格式,和JS的访问语法保持一致 - 可定制性:如果需要返回路径片段数组(比如
['a', 'b', 'c']),只需要把result.push(newPath.join(''))改成result.push([...newPath])就行
内容的提问来源于stack exchange,提问作者sd_30
相关产品推荐
相关产品推荐

