如何在对象与子数组嵌套结构中通过指定唯一键值对查找目标数据项
实现方法
针对这种规则固定的嵌套树结构,用深度优先遍历即可快速定位目标节点。由于JavaScript中对象是引用类型,拿到匹配节点的引用后直接修改属性,就会同步更新原树结构,不需要额外的回写操作。
基础递归实现(适配绝大多数场景)
递归逻辑非常直观:先校验当前节点是否匹配,不匹配就递归遍历所有子节点查找,找到就立刻返回结果。
function findNodeByFull(root, targetFull) { // 当前节点匹配直接返回 if (root.full === targetFull) return root; // 没有有效子节点直接终止当前分支查找 if (!Array.isArray(root.children)) return null; // 遍历子节点递归查找 for (const child of root.children) { const matchNode = findNodeByFull(child, targetFull); if (matchNode) return matchNode; } return null; }
使用示例
针对给出的样例树,查找并修改anotherFolder节点的代码如下:
const tree = { name: "Documents", type: "dir", full: "/home/adityam/Documents", children: [{ name: "file.txt", type: "file", full: "/home/adityam/Documents/file.txt", }, { name: "anotherFolder", type: "dir", full: "/home/adityam/Documents/anotherFolder", children: [], }], }; // 查找目标节点 const target = findNodeByFull(tree, "/home/adityam/Documents/anotherFolder"); if (target) { // 直接修改属性即可同步更新原树 target.children.push({ name: "test.md", type: "file", full: "/home/adityam/Documents/anotherFolder/test.md" }); }
超深树场景的迭代实现
如果树层级极深(通常是超过10000层的极端场景),递归可能触发调用栈溢出,可以换成手动维护遍历栈的迭代版本,查找逻辑和递归完全一致:
function findNodeByFullIterative(root, targetFull) { const waitCheckStack = [root]; while (waitCheckStack.length) { const current = waitCheckStack.pop(); if (current.full === targetFull) return current; if (Array.isArray(current.children)) { waitCheckStack.push(...current.children); } } return null; }
注意事项
- 实现完全不依赖节点的其他属性,不管节点增删多少自定义字段、属性值怎么变,只要符合「每个节点存在字符串类型
full属性、子节点存放在children数组」的基础规则,就能正常查找 - 函数返回的是原树中节点的引用,不是节点的拷贝,修改返回对象的任何属性都会直接反映到原结构上
- 如果需要按其他属性查找,只要把判断条件
root.full === targetFull换成对应属性的匹配逻辑即可,通用性很强
内容的提问来源于stack exchange,提问作者Aditya Mishra
相关产品推荐
相关产品推荐

