如何通过id删除深层嵌套对象数组中的指定节点及其子节点
核心问题排查
你的现有代码存在以下问题:
- 递归处理子节点时没有将过滤后的子节点数组回写到当前项,导致深层的过滤结果完全丢失
- reduce逻辑没有承接递归返回值,遍历到子节点后上层逻辑不知道子节点的处理结果
- 只做了当前层级的简单过滤,没有先递归处理完子节点再判断当前项是否要保留
修复后的可运行实现
const array = [ { node: { level: 0, id: 71, type: "block", style: { backgroundColor: "#548444", }, }, children: [ { node: { id: 85, type: "block", style: { backgroundColor: "#548444", fontSize: "19px", }, }, children: [ { node: { id: 955, type: "column", style: { backgroundColor: "#eee", fontSize: "28px", }, }, children: [ { node: { level: 3, parentId: 71, id: 732, type: "text", data: { text: "Ceci est un text", }, style: { color: "blue", fontSize: "13px", }, }, }, { node: { id: 353, parentId: 71, type: "text", data: { text: "Ceci est un text", }, style: { color: "blue", fontSize: "13px", }, }, }, ], }, ], }, ], }, { node: { level: 0, id: 7991, type: "block", style: { backgroundColor: "#548444", }, }, children: [ { node: { id: 8995, type: "block", style: { backgroundColor: "#548444", fontSize: "19px", }, }, children: [ { node: { id: 95995, type: "column", style: { backgroundColor: "#eee", fontSize: "28px", }, }, children: [ { node: { level: 3, parentId: 71, id: 73992, type: "text", data: { text: "Ceci est un text", }, style: { color: "blue", fontSize: "13px", }, }, }, { node: { id: 35993, parentId: 71, type: "text", data: { text: "Ceci est un text", }, style: { color: "blue", fontSize: "13px", }, }, }, ], }, ], }, ], }, ]; const removeNodeById = (arr, targetId, nestingKey = 'children') => { return arr.reduce((result, currentItem) => { // 匹配到目标ID直接跳过,不加入结果数组,连带子节点一并删除 if (currentItem.node.id === targetId) { return result } // 浅拷贝当前项避免修改原数据 const handledItem = {...currentItem} // 存在子节点则递归处理子节点 if (Array.isArray(handledItem[nestingKey])) { handledItem[nestingKey] = removeNodeById(handledItem[nestingKey], targetId, nestingKey) } // 处理完成的项加入结果 result.push(handledItem) return result }, []) } const res = removeNodeById(array, 35993, 'children') console.log(JSON.stringify(res, null, 2))
逻辑说明
- 从最外层数组开始遍历,每一层都用reduce生成新数组,不会修改原数据
- 每一项先判断ID是否匹配,匹配则直接过滤,自动连带所有子节点删除
- 不匹配的项先递归处理它的子节点数组,将处理后的子节点数组回写到当前项
- 支持任意层级的嵌套结构,不需要提前知道嵌套深度
内容的提问来源于stack exchange,提问作者NuoNuo LeRobot
相关产品推荐
相关产品推荐

