JavaScript如何不创建新数组移除非数字元素?解决splice索引丢失问题
原地移除数组非数字元素实现方案
问题根源
splice操作会直接修改原数组长度,正序遍历删除元素时,被删除位置后方的所有元素会整体前移一位,导致下一轮遍历会跳过前移上来的元素,也就是你遇到的索引丢失问题。另外不推荐使用for...in遍历数组,该方法会遍历数组的可枚举非索引属性,遍历效率和稳定性都不符合数组遍历的需求。
可行实现方案
方案1:倒序遍历 + splice(实现最简单)
倒序遍历的核心优势是删除当前索引元素时,只会影响已经完成遍历的后方索引,不会干扰还未遍历的前方索引,不会出现漏判的问题。
const filterNums = (nums) => { // 从数组最后一位开始倒序遍历 for (let i = nums.length - 1; i >= 0; i--) { if (typeof nums[i] !== 'number') { nums.splice(i, 1); } } return nums; }; console.log(filterNums([1, 'a', 2, 'b', true])); // 输出 [1, 2]
方案2:快慢指针法(性能最优)
该方案不需要频繁调用splice修改数组结构,仅通过一次遍历完成有效元素的覆盖,最后截断数组即可,时间复杂度为O(n),处理大数组时性能优势非常明显。
const filterNums = (nums) => { let slow = 0; // 快指针遍历全数组筛选有效元素 for (let fast = 0; fast < nums.length; fast++) { if (typeof nums[fast] === 'number') { // 慢指针记录有效元素的存放位置 nums[slow] = nums[fast]; slow++; } } // 截断慢指针后方的所有无效元素 nums.length = slow; return nums; }; console.log(filterNums([1, 'a', 2, 'b', true])); // 输出 [1, 2]
内容的提问来源于stack exchange,提问作者nandesuka
相关产品推荐
相关产品推荐

