如何将含父子关系的对象数组转换为嵌套对象?
转换父子关系数组为嵌套对象的解决方案
思路分析
要完成这个转换,核心是先建立节点与子节点的映射关系,再通过递归判断节点是否需要嵌套,最终构建出目标结构:
- 先将输入数组转换成节点-子节点映射表,方便快速查找任意节点的子节点。
- 确定根节点:即没有出现在任何子节点列表中的节点(这里是A1)。
- 递归构建嵌套结构:根据节点是否有子节点存在映射表中,决定返回数组还是嵌套对象。
代码实现
const input = [ { A1: [ "B1" ] }, { B1: [ "C11", "C12", "C13" ] }, { C11: [ "D100", "D111", "D112", "D113", "D131" ] }, { D100: [ "E1000", "E1100" ] } ]; // 1. 构建节点-子节点映射表 const nodeMap = {}; input.forEach(item => { const [node] = Object.keys(item); nodeMap[node] = item[node]; }); const hasChildrenNodes = new Set(Object.keys(nodeMap)); // 2. 查找根节点 const allChildren = new Set(input.flatMap(item => Object.values(item)[0])); const rootNode = Object.keys(nodeMap).find(node => !allChildren.has(node)); // 3. 递归生成嵌套结构 function buildNested(node) { if (!hasChildrenNodes.has(node)) { return []; } const children = nodeMap[node]; // 判断当前节点的子节点是否需要嵌套 const needNested = children.some(child => hasChildrenNodes.has(child)); if (!needNested) { return children; } return children.reduce((resultObj, child) => { resultObj[child] = buildNested(child); return resultObj; }, {}); } const finalResult = { [rootNode]: buildNested(rootNode) }; console.log(JSON.stringify(finalResult, null, 2));
代码说明
- 节点映射表:把输入数组中的每个节点和它的子节点列表对应起来,避免反复遍历数组查找。
- 根节点查找:通过收集所有子节点,找到不在子节点集合中的节点,就是整个结构的起点。
- 递归构建:
- 如果当前节点没有子节点列表(不在映射表中),直接返回空数组。
- 如果当前节点的子节点都没有自己的子节点列表,直接返回当前节点的子节点数组。
- 如果子节点中有需要嵌套的节点(存在于映射表中),则生成一个对象,每个子节点作为键,递归生成对应的值。
内容的提问来源于stack exchange,提问作者Andre S.
相关产品推荐
相关产品推荐

