JS循环结果重复冗余:数组奇偶分类异常问题及解决办法
嘿,我来帮你拆解下这个问题的原因,再给你几个靠谱的解决方案~
问题原因分析
你的代码出现重复值的核心问题有两个:
- 重复遍历数组:你在外层用了
for循环遍历数组索引,同时在循环内部又调用了arr.map()——map方法本身就会完整遍历整个数组。也就是说,每一次外层for的迭代(总共4次),都会触发map的4次遍历,相当于总共执行了4×4=16次push操作,每个元素被重复添加了4次。 - 判断条件错误:你用
i % 2 === 0判断的是数组索引的奇偶,而不是当前元素的奇偶。这就导致不管map遍历到哪个元素,都只会把外层for当前索引对应的元素反复push到数组里。
解决方案
这里提供几种不同风格的实现方式,都能得到正确的分组结果(顺便提一句:7是奇数,14是偶数,所以正确的偶数数组应该是[14],奇数数组是[7,3,17],你可能之前的预期写错啦):
方法1:修复原始逻辑(去掉多余的map)
既然已经用了for循环,就不需要再嵌套map了,直接判断当前元素的奇偶即可:
var arr = [7, 3, 14, 17] var o = { even: [], odd: [] } for (var i = 0; i < arr.length; i++) { const currentNum = arr[i]; // 判断元素本身的奇偶,而非索引 if (currentNum % 2 === 0) { o.even.push(currentNum) } else { o.odd.push(currentNum) } } console.log(o.even); // [14] console.log(o.odd); // [7, 3, 17]
方法2:用Array.reduce()(优雅的函数式写法)
reduce非常适合这种将数组归并为单一对象的场景,代码更简洁紧凑:
const arr = [7, 3, 14, 17]; const groupedResult = arr.reduce((acc, num) => { num % 2 === 0 ? acc.even.push(num) : acc.odd.push(num); return acc; }, { even: [], odd: [] }); // 传入初始分组对象 console.log(groupedResult.even); // [14] console.log(groupedResult.odd); // [7, 3, 17]
方法3:用filter分别筛选(直观易懂)
如果不需要一次性生成包含两个数组的对象,也可以用两次filter分别提取偶数和奇数:
const arr = [7, 3, 14, 17]; const evenArr = arr.filter(num => num % 2 === 0); const oddArr = arr.filter(num => num % 2 !== 0); console.log(evenArr); // [14] console.log(oddArr); // [7, 3, 17]
最佳实践建议
- 避免重复遍历数组:同时使用
for和map这类会遍历数组的方法,既浪费性能又容易引发逻辑错误; - 优先使用数组标准API:
reduce、filter等方法是JS的原生标准API,代码更简洁易读,也符合现代JS的函数式编程风格; - 区分索引和元素的判断逻辑:写代码时要明确自己是要判断索引的特征,还是元素本身的特征,避免混淆;
- 用
const/let替代var:var存在变量提升和函数作用域的问题,现代JS里推荐用const(值无需修改时)和let(值需要修改时)声明变量,代码更安全。
内容的提问来源于stack exchange,提问作者mike87
相关产品推荐
相关产品推荐

