如何将成对相邻重复元素数组重排为唯一值前置、重复值后置?
数组重排问题解决方案
一、使用sort()函数实现
你之前的代码失败是因为数组元素是字符串,并没有index属性,没法通过left.index - right.index来排序。要实现需求,可以借助临时计数器标记元素是第一次还是第二次出现,在排序回调里调整优先级:
const arr = ['1', '1', '2', '2', '3', '3']; const countMap = new Map(); const sortedArr = arr.sort((a, b) => { // 统计每个元素的出现次数 countMap.set(a, (countMap.get(a) || 0) + 1); countMap.set(b, (countMap.get(b) || 0) + 1); // 第一次出现的元素优先级更高,排在前面 if (countMap.get(a) === 1 && countMap.get(b) === 2) return -1; if (countMap.get(a) === 2 && countMap.get(b) === 1) return 1; // 同是首次或重复出现时,按元素本身排序 return a.localeCompare(b); }); console.log(sortedArr); // 输出: ['1','2','3','1','2','3']
注意:sort()是原地排序,且回调执行顺序不确定,这个方法依赖计数时机,仅适用于当前“元素恰好成对相邻”的场景。
二、更可靠的其他实现方法
如果不想依赖sort()的不确定性,还有两种更直观的方式:
方法1:拆分合并法
先提取所有唯一值,再将唯一值数组与自身拼接:
const arr = ['1', '1', '2', '2', '3', '3']; // 利用Set去重,提取原数组中的唯一值 const unique = [...new Set(arr)]; // 拼接得到目标数组 const sortedArr = [...unique, ...unique]; console.log(sortedArr); // 输出: ['1','2','3','1','2','3']
这个方法最简单,完全适配你的需求——因为原数组每个元素恰好出现两次,Set提取的唯一值顺序和原数组首次出现顺序一致。
方法2:分桶收集法
遍历原数组,将首次出现的元素放入前桶,重复出现的放入后桶,最后合并两个桶:
const arr = ['1', '1', '2', '2', '3', '3']; const firstBucket = []; const secondBucket = []; const seen = new Set(); for (const item of arr) { if (!seen.has(item)) { firstBucket.push(item); seen.add(item); } else { secondBucket.push(item); } } const sortedArr = firstBucket.concat(secondBucket); console.log(sortedArr); // 输出: ['1','2','3','1','2','3']
这个方法逻辑清晰,便于理解和调试,适合需要明确控制元素顺序的场景。
内容的提问来源于stack exchange,提问作者tech27
相关产品推荐
相关产品推荐

