如何使用Python将字典列表递归转换为层级结构?
构建经理层级关系的递归实现方案
问题背景
我有一段经理关系的JSON数据结构:
[ { "name": "manager_a", // 不管理其他经理 "manager": "manager_b" }, { "name": "manager_b", "manager": "manager_c" }, { "name": "manager_c" // 没有上级经理 }, { "name": "manager_d", // 不管理其他经理 "manager": "manager_c" }, ... ]
希望将其转换为体现层级关系的结构,示例如下:
[ { "name": "manager_c", // 没有上级经理 "reports": [ { "name": "manager_b", "reports": [ "manager_a" // 不管理其他经理 ] }, "manager_d" // 不管理其他经理 ] } ]
该层级无循环,但可能多级嵌套,我尝试过多种方法,始终搞不懂递归的实现逻辑。
实现方案
核心思路
先建立经理到直属下属的映射表,再通过递归遍历顶层经理(无上级的经理),逐层向下构建完整的层级结构。
步骤拆解
- 构建映射表:遍历原始数据,把每个经理的直属下属收集到对应的列表中,同时筛选出没有上级的顶层经理。
- 递归生成层级:对每个经理,检查是否有下属——有下属就生成包含
reports的对象,没下属就直接返回名称(或统一对象格式),递归处理所有嵌套层级。
JavaScript代码实现
function buildManagerHierarchy(managerList) { // 1. 初始化经理-下属映射表,收集顶层经理 const managerMap = {}; const topManagers = []; // 先给每个经理创建空的下属列表 managerList.forEach(item => { const { name } = item; if (!managerMap[name]) { managerMap[name] = []; } }); // 填充下属关系,标记顶层经理 managerList.forEach(item => { const { name, manager: superior } = item; if (!superior) { topManagers.push(name); } else { managerMap[superior].push(name); } }); // 2. 递归构建层级结构 function buildHierarchy(managerName) { const subordinates = managerMap[managerName]; // 没有下属,直接返回名称 if (subordinates.length === 0) { return managerName; } // 有下属,递归生成reports return { name: managerName, reports: subordinates.map(sub => buildHierarchy(sub)) }; } // 处理所有顶层经理,生成最终层级 return topManagers.map(manager => buildHierarchy(manager)); } // 测试用原始数据 const rawManagerData = [ { "name": "manager_a", "manager": "manager_b" }, { "name": "manager_b", "manager": "manager_c" }, { "name": "manager_c" }, { "name": "manager_d", "manager": "manager_c" } ]; // 执行函数并打印结果 console.log(JSON.stringify(buildManagerHierarchy(rawManagerData), null, 2));
代码说明
- 映射表环节:先给每个经理初始化空下属列表,避免后续找不到键的问题;再遍历数据把员工分配到直属上级的下属列表里,同时把没有上级的经理加入顶层列表。
- 递归函数:
buildHierarchy是核心,输入经理名称后,先查它的下属列表。如果没下属就返回名称;如果有下属,就生成带reports的对象,每个下属都调用这个函数,自动处理深层嵌套的层级。
格式扩展
如果希望所有层级都保持对象格式(即使没有下属),可以修改递归函数:
function buildHierarchy(managerName) { const subordinates = managerMap[managerName]; const hierarchyObj = { name: managerName }; // 有下属才添加reports字段 if (subordinates.length > 0) { hierarchyObj.reports = subordinates.map(sub => buildHierarchy(sub)); } return hierarchyObj; }
这样输出的结构会统一为对象,没有下属的经理不会有reports字段,也可以改为reports: []来保持字段统一。
内容的提问来源于stack exchange,提问作者Bruce Johnson
相关产品推荐
相关产品推荐

