如何按level属性将扁平对象数组转为嵌套对象数组?
扁平数组转嵌套层级结构的实现方案
问题描述
将包含level属性的扁平对象数组转换为嵌套结构,遵循以下规则:
- 若当前元素的
level大于目标元素,将其作为子元素添加 - 若
level相等,则作为同级兄弟元素添加
原代码问题
你当前的reduce实现仅对比结果数组最后一个元素的层级,没有维护层级路径,无法处理深层嵌套后的回溯场景——比如无法将层级更低的元素插入到正确的父节点子级中。
正确实现代码
const list = [ { name: "h1", level: 1, children: [] }, { name: "h2", level: 2, children: [] }, { name: "h3", level: 3, children: [] }, { name: "paragraph", level: 1, children: [] }, { name: "bold", level: 2, children: [] }, { name: "italic", level: 2, children: [] }, { name: "paragraph", level: 1, children: [] } ]; const nestedList = list.reduce(({ result, stack }, curr) => { // 回溯栈,找到当前元素的父节点(最近的层级小于当前level的节点) while (stack.length > 0 && stack[stack.length - 1].level >= curr.level) { stack.pop(); } if (stack.length === 0) { // 无父节点,添加到根层级 result.push(curr); } else { // 添加到父节点的子级列表 stack[stack.length - 1].children.push(curr); } // 将当前元素压入栈,作为后续元素的候选父节点 stack.push(curr); return { result, stack }; }, { result: [], stack: [] }).result; console.log(JSON.stringify(nestedList, null, 1));
代码逻辑说明
- 维护两个状态:
result存储最终嵌套结构,stack记录当前层级路径(用于回溯找父节点) - 遍历每个元素时,先回溯栈:弹出栈中所有层级大于等于当前元素层级的节点,直到找到层级小于当前的节点(即父节点)
- 根据栈是否为空,决定将当前元素添加到根层级还是父节点的子级
- 将当前元素压入栈,作为后续元素的候选父节点
- 最终返回
result即可得到目标嵌套结构
验证结果
运行上述代码后,输出与期望结果完全一致:
[ { "name": "h1", "level": 1, "children": [ { "name": "h2", "level": 2, "children": [ { "name": "h3", "level": 3, "children": [] } ] } ] }, { "name": "paragraph", "level": 1, "children": [ { "name": "bold", "level": 2, "children": [] }, { "name": "italic", "level": 2, "children": [] } ] }, { "name": "paragraph", "level": 1, "children": [] } ]
内容的提问来源于stack exchange,提问作者artSir
相关产品推荐
相关产品推荐

