如何获取多维数组子元素索引并通过splice方法删除指定值
问题分析
你需要实现的功能是传入多维数组和目标数值,删除所有子数组中包含的目标值,保留原有子数组结构后返回。你用「遍历找索引+splice删除」的思路本身是可行的,代码运行异常是几个写法错误导致的。
现有代码的核心错误
- 第一个循环的
for (elem in newArr[i])写法完全错误:一是直接把函数入参elem(也就是你要找的目标值)声明成了循环变量,直接覆盖了原本的目标值;二是for...in遍历数组拿到的是字符串类型的索引,不是元素值,此时你调用indexOf(elem)找的是字符串格式的索引值,自然全返回-1。 - 第二个循环里
return newArr写在了外层for循环的内部,第一次遍历完第一个子数组就直接终止函数返回了,后面的所有子数组根本不会进入处理逻辑。 - 遍历数组用
splice删除元素时如果从前往后遍历,删除元素后数组长度会缩短,后续元素的索引会往前移,很容易漏删元素。 - 你用
[...arr]做的是浅拷贝,内层子数组仍然是原数组的引用,这个问题在当前场景下不影响功能,但如果需求要求完全不修改原输入数组,需要额外做深拷贝处理。
按你原有思路修正后的代码
如果严格遵循「for循环找索引+splice删除」的逻辑,修正后的代码如下:
function filteredArray(arr, elem) { // 拷贝外层数组,避免直接修改原输入的外层数组 const newArr = [...arr]; const outerLength = newArr.length; for (let i = 0; i < outerLength; i++) { const currentSubArr = newArr[i]; // 从后往前遍历子数组,避免splice删除元素后导致索引错位漏删 for (let j = currentSubArr.length - 1; j >= 0; j--) { if (currentSubArr[j] === elem) { // 从当前匹配到的索引位置删除1个元素 currentSubArr.splice(j, 1); } } } return newArr; } // 测试用例 console.log(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3)); // 运行结果:[[2], [1, 6], [13, 26], [19, 9]]
更简洁的实现方案
如果题目没有强制要求必须使用for循环和splice,用数组内置方法实现会更简洁,不需要手动处理索引错位问题,也不会修改原数组:
function filteredArray(arr, elem) { return arr.map(subArr => subArr.filter(item => item !== elem)); }
逻辑很简单:遍历外层每个子数组,用filter过滤掉所有等于目标值的元素,返回过滤后的新子数组,最后map将所有处理完的子数组拼成新的结果数组返回,代码可读性和鲁棒性都更高,是实际开发中推荐的写法。
内容的提问来源于stack exchange,提问作者Umme Habiba
相关产品推荐
相关产品推荐

