JavaScript如何递归删除指定ID的父项及其关联子项?
递归移除指定parentId及其所有关联子项的实现方案
针对这种分散的数组结构,我们可以通过建立映射+递归收集待删除ID的方式高效实现需求,步骤如下:
实现思路
- 构建快速查找映射:将数组中每个项的
parentId作为键,对应项作为值存入对象,这样可以O(1)时间找到任意parentId对应的项,避免重复遍历数组。 - 递归收集所有待删除的parentId:从目标
parentId开始,先将其加入待删除集合;接着遍历该项的children中的每个childId,如果这个childId是某个项的parentId,就递归收集这个parentId及其子项对应的关联ID。 - 过滤原数组:保留所有
parentId不在待删除集合中的项。
代码实现
function removeRelatedItems(arr, targetParentId) { // 1. 构建parentId到项的映射 const parentMap = arr.reduce((map, item) => { map[item.parentId] = item; return map; }, {}); // 2. 递归收集所有需要删除的parentId const removedIds = new Set(); function collectRemovedIds(currentId) { if (removedIds.has(currentId)) return; // 加入当前ID到待删除集合 removedIds.add(currentId); // 找到当前ID对应的项 const currentItem = parentMap[currentId]; if (!currentItem) return; // 遍历所有childId,递归收集对应的parentId currentItem.children.forEach(child => { const childId = child.childId; if (parentMap[childId]) { collectRemovedIds(childId); } }); } // 启动递归收集 collectRemovedIds(targetParentId); // 3. 过滤数组,保留不在待删除集合中的项 return arr.filter(item => !removedIds.has(item.parentId)); } // 测试示例 const arr = [{ parentId: 1, children: [ { childId: 11 }, { childId: 21 }, { childId: 31 }, ] }, { parentId: 31, children: [ { childId: 111 }, { childId: 211 }, { childId: 311 }, ] }, { parentId: 7, children: [ { childId: 711 }, { childId: 721 }, { childId: 731 }, ] }, { parentId: 311, children: [ { childId: 3111 }, { childId: 3211 }, { childId: 3311 }, ] }]; // 移除parentId=1的关联项 const result = removeRelatedItems(arr, 1); console.log(result); // 输出:[{ parentId:7, children: [...] }]
方案优势
- 时间效率高:构建映射、收集删除ID、过滤数组三个步骤均为线性时间复杂度O(n),整体性能优于多次遍历查找的实现。
- 逻辑清晰:拆分步骤后,每个函数职责单一,易于理解和维护。
- 边界友好:自动处理目标
parentId不存在、childId无对应项等情况,不会抛出错误。
内容的提问来源于stack exchange,提问作者user17692616
相关产品推荐
相关产品推荐

