JavaScript数组元素移除函数异常:无法清空数组导致测试失败
问题排查:removeFromArray函数无法移除所有元素
问题场景
正在完成Odin项目第四个任务,实现的removeFromArray函数用于移除数组指定元素,前4个测试用例均通过,但第5个要求移除所有元素的测试失败,调用removeFromArray([1,2,3,4],1,2,3,4)后返回[3,4]而非空数组。
原实现代码
const removeFromArray = function (array, ...deleteElement) { for (let i = 0; i < array.length; i++) { if (array.includes(deleteElement[i])) { array.splice(array.indexOf(deleteElement[i]), 1); } } return array; }; const randomArray = [1, 2, 3, 4]; console.log(removeFromArray(randomArray, 1, 2, 3, 4));
测试用例
const removeFromArray = require('./removeFromArray') describe('removeFromArray', () => { test('removes a single value', () => { expect(removeFromArray([1, 2, 3, 4], 3)).toEqual([1, 2, 4]); }); test('removes multiple values', () => { expect(removeFromArray([1, 2, 3, 4], 3, 2)).toEqual([1, 4]); }); test('ignores non present values', () => { expect(removeFromArray([1, 2, 3, 4], 7, "tacos")).toEqual([1, 2, 3, 4]); }); test('ignores non present values, but still works', () => { expect(removeFromArray([1, 2, 3, 4], 7, 2)).toEqual([1, 3, 4]); }); test.skip('can remove all values', () => { expect(removeFromArray([1, 2, 3, 4], 1, 2, 3, 4)).toEqual([]); }); test.skip('works with strings', () => { expect(removeFromArray(["hey", 2, 3, "ho"], "hey", 3)).toEqual([2, "ho"]); }); test.skip('only removes same type', () => { expect(removeFromArray([1, 2, 3], "1", 3)).toEqual([1, 2]); }); });
问题根源
- 循环逻辑完全错误:原循环用
array.length作为终止条件,同时用循环变量i去索引deleteElement数组,两者没有对应关系。当执行splice移除元素时,原数组长度动态缩短,导致循环提前终止——比如测试用例中初始数组长度为4,删除第一个元素后长度变为3,i递增到2时,数组长度已经是2,循环直接结束,只处理了前两个要删除的元素。 - 判断条件颠倒:
array.includes(deleteElement[i])是检查待删除元素是否在原数组中,但正确逻辑应该是检查原数组元素是否在待删除列表里,而非反过来。 - 直接修改原数组:虽然前几个测试通过,但直接修改传入的数组会产生副作用,可能导致调用方的原始数组被意外修改。
修复方案
推荐使用数组filter方法创建并返回新数组,逻辑简洁且无副作用:
const removeFromArray = function(array, ...deleteElements) { return array.filter(item => !deleteElements.includes(item)); };
如果一定要用循环修改原数组(不推荐),需遍历待删除元素列表,同时处理重复元素:
const removeFromArray = function(array, ...deleteElements) { for (const elem of deleteElements) { let index; // 循环移除所有匹配的元素 while ((index = array.indexOf(elem)) !== -1) { array.splice(index, 1); } } return array; };
验证
修复后调用removeFromArray([1,2,3,4],1,2,3,4)会返回空数组,所有测试用例均可通过。
内容的提问来源于stack exchange,提问作者user667199
相关产品推荐
相关产品推荐

