如何将数组对象迭代嵌套为层级对象(TypeScript实现)
问题描述
我有如下数组:
const arr = [ { parent: 'A', children: ['B'], }, { parent: 'B', children: ['C'], }, { parent: 'C', children: ['D'] }];
希望编写一个函数,将该数组转换为如下层级嵌套对象:
const result = { parent: 'A', children: [{ parent: 'B', children: [{ parent: 'C', children: [{ parent: 'D', children: [] }] }] }] };
结果类型定义如下:
type Result = { parent: string; children: Result[]; };
我目前的尝试代码如下:
type TInput = { parent: string; children: string[]; }; type Result = { parent: string; children: Result[]; }; // can assume we know initial parent is 'A' const fn = (parent: string, inputArr: TInput[]) => { const result: TResult[] = []; let newParent: string[] = []; while (newParent.length !== 0) { const index = inputArr.findIndex( (input) => input.parent === parent ); result.push({ parent: inputArr[index].parent, children: [], // need to populate on next pass? }); newParent = inputArr[index].children; } return result; };
我不清楚输入数组的长度,但已知初始父节点为'A',请求帮助完善该函数。
解决方案
你的代码存在几个核心问题:
- 初始
newParent为空数组,循环根本不会执行 - 函数返回数组,但需求是返回单个嵌套对象(根节点为'A')
- 没有递归或迭代逻辑填充子节点层级
以下提供两种可行的实现方式:
递归实现(直观简洁)
递归是处理层级结构最直观的方式,逻辑清晰易懂:
type TInput = { parent: string; children: string[]; }; type Result = { parent: string; children: Result[]; }; const buildNestedTree = (currentParent: string, inputArr: TInput[]): Result => { // 查找当前父节点对应的输入项 const currentItem = inputArr.find(item => item.parent === currentParent); // 若找不到对应项,返回空结构(可根据需求调整为抛出错误) if (!currentItem) { return { parent: currentParent, children: [] }; } // 递归处理每个子节点,生成对应的子树 const children = currentItem.children.map(child => buildNestedTree(child, inputArr)); return { parent: currentParent, children }; }; // 使用示例 const arr = [ { parent: 'A', children: ['B'] }, { parent: 'B', children: ['C'] }, { parent: 'C', children: ['D'] } ]; const result = buildNestedTree('A', arr); console.log(result);
迭代实现(避免递归深度限制)
如果输入数组层级极深,递归可能触发栈溢出,此时可以用迭代方式实现:
type TInput = { parent: string; children: string[]; }; type Result = { parent: string; children: Result[]; }; const buildNestedTree = (rootParent: string, inputArr: TInput[]): Result => { // 将输入数组转为Map,避免重复查找,提升性能 const itemMap = new Map(inputArr.map(item => [item.parent, item])); // 初始化根节点 const root: Result = { parent: rootParent, children: [] }; // 用栈存储待处理的节点,每个元素包含当前节点和对应的父节点键 const stack = [{ currentNode: root, parentKey: rootParent }]; while (stack.length > 0) { const { currentNode, parentKey } = stack.pop()!; const currentItem = itemMap.get(parentKey); if (currentItem) { // 为每个子节点创建Result对象 currentNode.children = currentItem.children.map(child => ({ parent: child, children: [] })); // 将子节点推入栈,继续处理它们的子节点 currentNode.children.forEach(childNode => { stack.push({ currentNode: childNode, parentKey: childNode.parent }); }); } } return root; }; // 使用示例 const arr = [ { parent: 'A', children: ['B'] }, { parent: 'B', children: ['C'] }, { parent: 'C', children: ['D'] } ]; const result = buildNestedTree('A', arr); console.log(result);
代码说明
- 递归实现:每次找到当前父节点的输入项,对每个子节点递归调用函数生成子树,最终组合成完整嵌套结构
- 迭代实现:用栈模拟递归过程,通过Map优化查找效率,逐个处理节点并填充子层级
- 两种方式都支持任意长度的输入数组,只要层级关系连续即可
内容的提问来源于stack exchange,提问作者Iain McHugh
相关产品推荐
相关产品推荐

