如何从树形数组中移除指定Key的元素?
问题原因分析
- 返回undefined的原因:
Array.prototype.forEach()是无返回值的方法,它仅遍历数组执行回调逻辑,不会返回任何结果。你直接console.logforEach的执行结果,自然输出undefined。 - 遍历删除的索引问题:正向遍历数组时使用
splice删除元素,会导致数组长度缩短,后续元素的索引前移,可能跳过部分需要处理的元素。比如删除第i个元素后,原i+1位置的元素会移到i位置,但下一次循环i递增,会直接跳过这个元素。
修正后的实现方案
优化点:
- 把
inputArray转为Set,将includes的O(n)查找复杂度降为O(1),提升性能。 - 使用
filter替代splice,避免索引错乱问题,代码更简洁易读。 - 明确处理逻辑:遍历所有层级的
children数组,移除其中key存在于inputArray中的元素(符合你备注中的需求:保留父元素,仅移除子层级中匹配的元素)。
代码示例:
const inputArray = [ "Oxygen-a3b8be32-c36e-a02e-37f4-a35239e0cedb", "633ac872e78fa7ebee03b8bf", "5e69dbd7-5fee-67a9-c73f-4656f9b90715", "d484558b-4717-b0b8-db07-68288afb4f6a", "63922aac4ff08f52d71fa891", "33a3182b-93a4-84b9-4c49-c955a8416197", ]; const originalArray = [{ title: "Animals", key: "d484558b-4717-b0b8-db07-68288afb4f6a", children: [{ title: "Color", key: "63922aac4ff08f52d71fa891", children: [{ title: "Black", key: "Black-9e994ed2-823b-d1d6-4613-91d43f570fec", }, { title: "White", key: "White-5d0b102a-2555-8f7c-d471-cc82a5bd9c01", }, ], }, ], }, { title: "Elements", key: "5e69dbd7-5fee-67a9-c73f-4656f9b90715", children: [{ title: "Non metals", key: "633ac872e78fa7ebee03b8bf", children: [{ title: "Carbon", key: "Carbon-e443daa4-def4-9830-796e-ee8c5a1f41d4", }, { title: "Nitrogen", key: "Nitrogen-c2922569-0b2d-0e07-454d-d8411af701b7", }, { title: "Oxygen", key: "Oxygen-a3b8be32-c36e-a02e-37f4-a35239e0cedb", }, ], }, ], }, { title: "Planets", key: "33a3182b-93a4-84b9-4c49-c955a8416197", children: [{ title: "Composition", key: "63b3d5cd12c06ba7ce353f76", children: [{ title: "Chthonian planet", key: "Chthonian planet-b3c593c1-d29e-5e14-1b11-2241e8ef2be6", }, { title: "Carbon planet", key: "Carbon planet-07d67d62-afcf-fbcf-a8e8-75081cb44c2f", }, ], }, ], }, ]; // 转为Set提升查找性能 const inputKeys = new Set(inputArray); // 递归处理所有层级的children function filterChildren(children) { // 保留key不在inputKeys中的元素 const filtered = children.filter(item => !inputKeys.has(item.key)); // 递归处理每个元素的子children filtered.forEach(item => { if (item.children) { item.children = filterChildren(item.children); } }); return filtered; } // 处理顶层数组中每个元素的children originalArray.forEach(item => { if (item.children) { item.children = filterChildren(item.children); } }); // 打印修改后的数组,不再输出undefined console.log("🚀 ~ 修改后的数组", originalArray);
效果验证:
- 对于
Elements的子元素Non metals,会保留该元素,仅移除其children中的Oxygen(符合你备注中的需求)。 - 所有层级中
key匹配inputArray的元素都会被移除,同时避免了遍历删除的索引问题。 - 最终打印的是修改后的数组,不再输出
undefined。
内容的提问来源于stack exchange,提问作者Gabriel
相关产品推荐
相关产品推荐

