如何在不改变偶数元素索引的前提下排序数组中的奇数元素?
问题分析与解决方案
首先咱们来看你的代码存在的几个关键问题:
- 重复排序的效率问题:你在
reduce的回调里,每添加一个奇数就调用一次sort(),这完全没必要——多次排序会额外消耗性能,应该先把所有奇数收集完,再统一排序一次。 - 核心逻辑缺失:你的函数最后只返回了排序后的奇数数组,完全没有处理原数组的结构!这就是为什么你得不到预期输出的根本原因——你没有把排序后的奇数放回原数组对应的奇数位置,也没保留偶数的原有位置。
正确的实现思路
要实现“仅排序奇数、保持偶数位置不变”的需求,咱们可以分成两步走:
- 从原数组中提取所有奇数,对它们进行升序排序;
- 遍历原数组,遇到奇数时就用排序好的奇数数组里的元素依次替换,遇到偶数则直接保留。
修正后的代码
function myFunction(array) { // 第一步:收集所有奇数并进行数字升序排序(注意要传比较函数,避免字符串排序坑) const sortedOdds = array.filter(val => val % 2 !== 0).sort((a, b) => a - b); // 用一个指针来跟踪要取出的排序后奇数的位置 let oddPointer = 0; // 第二步:遍历原数组,替换奇数,保留偶数 return array.map(val => { if (val % 2 !== 0) { // 取出当前指针位置的奇数,指针自增 return sortedOdds[oddPointer++]; } // 偶数直接返回,保持位置不变 return val; }); } console.log(myFunction([5, 3, 2, 8, 1, 4])); // 输出:[1, 3, 2, 8, 5, 4]
代码解释
filter(val => val % 2 !== 0):快速筛选出原数组里的所有奇数;sort((a, b) => a - b):这里一定要传比较函数,因为JavaScript数组的默认sort()是按字符串Unicode码点排序的,如果直接用sort(),像[10, 2]会被排成[10, 2],而不是我们要的数字升序;map遍历原数组:通过oddPointer指针依次取出排序后的奇数,替换原数组中的奇数元素,偶数元素则直接保留,完美实现了“偶数位置不变,奇数排序”的需求。
内容的提问来源于stack exchange,提问作者Devmix
相关产品推荐
相关产品推荐

