如何按元素重复次数降序排列数组元素(次数相同则升序)
问题:按重复次数降序、元素升序排列数组元素
需求:将数组元素按重复次数降序输出,重复次数多的排在最前;若元素重复次数相同,则按元素本身升序排列。
示例1:
原数组:const scores = [2,3,2,2,24,10,10,10,10,10,11,10,21,29,2];
输出优先级:10(重复6次)> 2(重复4次)> 其余元素(各重复1次)
示例2:
原数组:const scores = [2,3,2,2,24,10,10,10,11,21,10,29,2];
输出优先级:2、10(均重复4次,按元素升序排列)> 其余元素
已实现元素重复次数统计的代码:
const scores = [2,3,2,2,24,10,10,10,10,10,11,10,21,29,2]; let elementCnt = {}; scores.forEach((val) => { elementCnt[val] = (elementCnt[val] || 0) + 1; }); console.log(elementCnt); // 输出:{ '2': 4, '3': 1, '10': 6, '11': 1, '21': 1, '24': 1, '29': 1 }
解决方案
实现步骤
- 将统计次数的对象转换为二维数组:使用
Object.entries()把elementCnt转成[元素字符串, 次数]的数组形式,方便后续排序。 - 自定义排序规则:
- 优先按重复次数降序排列:通过
b[1] - a[1]实现次数多的在前。 - 若次数相同,按元素升序排列:将元素字符串转为数字后,用
Number(a[0]) - Number(b[0])实现数值升序,避免字符串排序的误差(比如'10'作为字符串会比'2'小)。
- 优先按重复次数降序排列:通过
- 提取排序后的元素(可选):如果只需要元素列表,用
map()提取数组中的元素并转为数字;如果需要保留次数,可跳过此步骤。
完整代码
const scores = [2,3,2,2,24,10,10,10,10,10,11,10,21,29,2]; let elementCnt = {}; // 统计元素出现次数 scores.forEach((val) => { elementCnt[val] = (elementCnt[val] || 0) + 1; }); // 转换数组并按规则排序 const sortedElements = Object.entries(elementCnt) .sort((a, b) => { // 先按次数降序 if (b[1] !== a[1]) { return b[1] - a[1]; } // 次数相同则按元素数值升序 return Number(a[0]) - Number(b[0]); }) // 提取元素并转为数字 .map(item => Number(item[0])); // 输出结果 console.log(sortedElements.join(', ')); // 示例1输出:10, 2, 3, 11, 21, 24, 29 // 示例2输出:2, 10, 3, 11, 21, 24, 29
说明
Object.entries(elementCnt)会把统计对象转换为类似['2', 4], ['10', 6]的二维数组,让排序逻辑可以直接作用于数组元素。- 排序函数中先判断次数是否相同,不同则按次数降序;相同则按元素数值升序,确保符合需求的排序逻辑。
- 最后用
join(', ')将数组转为逗号分隔的字符串输出,也可以直接使用sortedElements数组进行后续操作。
内容的提问来源于stack exchange,提问作者user2159616
相关产品推荐
相关产品推荐

