
本文详解如何为具有复杂父子关系(如一个子节点拥有多个父节点)的 JSON 数据结构准确分配 depth 字段,避免传统递归遍历中因共享引用或遍历逻辑错误导致的深度丢失问题。
本文详解如何为具有复杂父子关系(如一个子节点拥有多个父节点)的 json 数据结构准确分配 `depth` 字段,避免传统递归遍历中因共享引用或遍历逻辑错误导致的深度丢失问题。
在处理树形结构数据时,为每个节点标注层级深度(depth)是常见需求。但当节点存在多个父节点(即 DAG — 有向无环图,而非纯树)时,传统基于单根 DFS 的深度赋值方法容易失效:例如某个节点被多个父节点引用,若仅从某一路径遍历,其余路径可能跳过该节点,导致 depth 未被设置或被错误覆盖。
关键在于:深度应取所有可达路径中的最小值(即最近根距离)。但由于本例中所有节点最终都可追溯至 "meta"(无 parentids 的根),且结构无环,我们可采用更稳健的策略——自顶向下广度优先(BFS)或递归深度优先(DFS)+ 安全赋值,确保每个节点至少被访问一次,并用 ??=(空值合并赋值)保障首次赋值不被覆盖。
以下是优化后的完整实现:
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
const data = [
{ title: "meta", parentids: [] },
{ title: "instagram", parentids: ["meta"] },
{ title: "facebook", parentids: ["meta"] },
{ title: "whatsapp", parentids: ["meta"] },
{ title: "zuckerberg", parentids: ["instagram", "facebook"] },
];
// 步骤1:构建标题到对象的映射,并初始化 children 数组
const titleLookup = Object.fromEntries(
data.map(node => {
node.children = []; // 原地添加 children,避免浅拷贝陷阱
return [node.title, node];
})
);
// 步骤2:建立父子关系(一个子节点可被多个父节点引用)
for (const node of data) {
for (const pid of node.parentids) {
if (titleLookup[pid]) {
titleLookup[pid].children.push(node);
}
}
}
// 步骤3:递归赋深度 —— 仅在 depth 未定义时写入,确保最小深度生效
const assignDepth = (nodes, depth = 0) => {
for (const node of nodes) {
node.depth ??= depth; // ✅ 关键:仅当 depth 为 undefined/null 时赋值
assignDepth(node.children, depth + 1);
}
};
// 从所有根节点开始(parentids 为空者),此处仅 "meta"
const roots = data.filter(node => node.parentids.length === 0);
assignDepth(roots);
console.log(JSON.stringify(data, null, 2));输出结果中每个节点都将拥有正确的 depth 值:
- "meta" → depth: 0
- "instagram", "facebook", "whatsapp" → depth: 1
- "zuckerberg" → depth: 2(因它位于 instagram 和 facebook 的子层)
⚠️ 重要注意事项:
- 避免浅拷贝误导:[...data] 仅复制数组引用,内部对象仍是原对象。若需真正隔离修改,请用 JSON.parse(JSON.stringify(data))(适用于纯 JSON 数据)或手动深拷贝函数。
- 优先使用 const:除极少数需重赋值的变量(如循环计数器),一律用 const 提升代码可预测性与可维护性。
- ??= 而非 =:防止多路径遍历时深度被更大值覆盖,确保首次到达即标记最短路径深度。
- 不依赖“唯一根”假设:若数据含多个独立根(如多个 parentids: [] 节点),上述 roots 数组提取逻辑天然兼容,无需修改。
该方案兼顾简洁性、健壮性与可读性,适用于真实业务中常见的多父级组织架构、标签系统或权限继承等场景。

















