如何在深度嵌套对象数组中拼接父节点名称更新id属性?
处理嵌套对象数组的ID拼接问题
问题描述
需要将嵌套对象数组中每个节点的id属性,更新为当前节点的name属性与所有父节点的name属性以/分隔拼接的结果。
原数据
treeData = [{ name: 'Infiniti', id: '', children: [{ name: 'G50', id: '', children: [{ name: 'Pure AWD', id: '' }, { name: 'Luxe', id: '' }, ], }, { name: 'QX50', id: '', children: [{ name: 'Pure AWD', id: '' }, { name: 'Luxe', id: '' }, ], }, ], }, { name: 'BMW', id: '', children: [{ name: '2 Series', id: '', children: [{ name: 'Coupé', id: '' }, { name: 'Gran Coupé', id: '' }, ], }, { name: '3 Series', id: '', children: [{ name: 'Sedan', id: '' }, { name: 'PHEV', id: '' }, ], }, ], }, ];
预期结果
[{ name: 'Infiniti', id: 'Infiniti', children: [{ name: 'G50', id: 'Infiniti/G50', children: [{ name: 'Pure AWD', id: 'Infiniti/G50/Pure AWD' }, { name: 'Luxe', id: 'Infiniti/G50/Luxe' }, ], }, { name: 'QX50', id: 'Infiniti/QX50', children: [{ name: 'Pure AWD', id: 'Infiniti/QX50/Pure AWD' }, { name: 'Luxe', id: 'Infiniti/QX50/Luxe' }, ], }, ], }, { name: 'BMW', id: 'BMW', children: [{ name: '2 Series', id: 'BMW/2 Series', children: [{ name: 'Coupé', id: 'BMW/2 Series/Coupé' }, { name: 'Gran Coupé', id: 'BMW/2 Series/Gran Coupé' }, ], }, { name: '3 Series', id: 'BMW/3 Series', children: [{ name: 'Sedan', id: 'BMW/3 Series/Sedan' }, { name: 'PHEV', id: 'BMW/3 Series/PHEV' }, ], }, ], }, ];
现有代码问题
你当前使用reduce的代码没有传递父节点的路径信息,也没有处理id的赋值逻辑,因此无法生成包含父节点name的拼接ID。
function updateTreeData(array) { return array.reduce((returnValue, currentValue) => { if (currentValue.children != null) { returnValue.push(Object.assign({}, currentValue, { children: this.updateTreeData(currentValue.children) })) } return returnValue }, []); } console.log(updateTreeData(treeData))
解决方案
可以通过递归函数+传递父路径参数的方式实现需求,用map替代reduce更直观,因为我们需要转换数组中的每个元素:
function updateTreeData(array, parentPath = '') { return array.map(node => { // 生成当前节点的ID:父路径为空则直接用当前name,否则拼接父路径与当前name const currentId = parentPath ? `${parentPath}/${node.name}` : node.name; // 递归处理子节点,将当前节点的ID作为子节点的父路径 const updatedChildren = node.children ? updateTreeData(node.children, currentId) : undefined; // 返回新的节点对象,避免修改原数据 return { ...node, id: currentId, children: updatedChildren }; }); } // 调用函数并输出结果 const updatedTree = updateTreeData(treeData); console.log(updatedTree);
代码说明
- 新增
parentPath参数,默认值为空字符串,用于传递当前节点的父级路径 - 使用
map遍历数组,对每个节点生成新的id,并递归处理子节点时传递当前节点的完整路径 - 使用扩展运算符
...创建新对象,不会修改原数据结构,保证数据不可变性
内容的提问来源于stack exchange,提问作者Rolex
相关产品推荐
相关产品推荐

