如何通过递归实现层级关联对象的删除?
递归删除层级对象的正确实现方法
你现在的代码有几个明显问题:
- 只处理了
findSubTask里的第一个子对象,同一层级的其他子节点直接被忽略了(比如如果删除id=1时有多个同级子节点,就会漏删) - 递归逻辑只盯着单个子节点的下一级,没覆盖所有层级的子孙节点
- 直接修改数组的写法容易出问题,最好保持纯函数的写法,返回新数组而不是修改原数组
下面给你两种靠谱的实现方式:
方案一:先收集所有要删除的ID,再过滤数组
这种方法逻辑最清晰,先递归找出目标节点及其所有子孙节点的ID,再一次性过滤掉这些节点:
// 递归收集所有需要删除的ID(目标ID + 所有子孙ID) const getDeleteIds = (array, targetId) => { let ids = [targetId]; // 找到当前ID的所有直接子节点 const children = array.filter(item => item.parentId === targetId); // 递归收集每个子节点的所有子孙ID children.forEach(child => { ids = [...ids, ...getDeleteIds(array, child.id)]; }); return ids; }; const deleteFunc = (array, targetId) => { const deleteIds = getDeleteIds(array, targetId); // 过滤掉所有在删除列表里的节点 return array.filter(item => !deleteIds.includes(item.id)); }; // 测试示例 const arr = [ {title: 'one', id: 1, parentId: null}, {title: 'two', id: 2, parentId: 1}, {title: 'three', id: 3, parentId: null}, {title: 'four', id: 4, parentId: 2}, {title: 'five', id: 5, parentId: 2}, {title: 'six', id: 6, parentId: 5}, {title: 'seven', id: 7, parentId: 3}, ]; console.log(deleteFunc(arr, 1)); // 输出符合预期:[{title: 'three', id: 3, parentId: null}, {title: 'seven', id: 7, parentId: 3}]
这个方法的优势是逻辑直观,容易维护,而且是纯函数(不会修改原数组),避免了副作用。
方案二:直接递归过滤数组
另一种思路是在过滤时直接判断当前节点是否属于要删除的分支:
const deleteFunc = (array, targetId, parentMap = null) => { // 第一次调用时,先构建parentId到子节点ID的映射,方便快速查找 if (!parentMap) { parentMap = array.reduce((map, item) => { const pid = item.parentId ?? 'root'; if (!map[pid]) map[pid] = []; map[pid].push(item.id); return map; }, {}); } // 递归判断节点是否属于要删除的分支 const shouldDelete = (id) => { if (id === targetId) return true; // 找到当前节点的父节点ID const parentItem = array.find(item => item.id === id); if (!parentItem || parentItem.parentId === null) return false; // 递归判断父节点是否需要删除 return shouldDelete(parentItem.parentId); }; return array.filter(item => !shouldDelete(item.id)); }; // 测试示例 console.log(deleteFunc(arr, 1));
这个方案不需要提前收集所有ID,但因为每次判断都要查找父节点,数据量大的时候性能会比第一种方案差一些,适合小数据量场景。
总结一下,优先选第一种方案,性能和可读性都更好。另外注意尽量用纯函数的写法,减少不必要的副作用。
内容的提问来源于stack exchange,提问作者vinograd
相关产品推荐
相关产品推荐

