JavaScript统计数组数字出现次数并按数字升序排序的问题
问题本质原因
普通 JavaScript 对象的键遍历顺序有固定规则,不会完全按照插入顺序排列:
- 先遍历所有可转换为非负整数的键,按数值升序排列
- 剩余字符串类型键(包括负数的字符串形式、非数字字符串)才会按插入顺序排列
所以你哪怕按升序插入负数键,这些键依然会排在非负数字键的后面,达不到全量升序的效果。
解决方案
方案1:使用Map存储结果(推荐)
ES6 新增的 Map 结构会严格按照键的插入顺序保存数据,完美适配需求:
let arr = [9,-10,2,9,6,1,2,10,-8,-10,2,9,6,1]; // 统计数字出现次数 let numCount = {}; for(let num of arr){ numCount[num] = numCount[num] ? numCount[num] + 1 : 1; } // 转数组后按数值升序排序 let sortedArray = Object.entries(numCount).sort((a,b) => Number(a[0]) - Number(b[0])); // 存入Map,保留插入顺序 let sortedResult = new Map(sortedArray); // 验证输出 console.log(sortedResult); // 输出:Map(7) { '-10' => 2, '-8' => 1, '1' => 2, '2' => 3, '6' => 2, '9' => 3, '10' => 1 } // 如果需要输出和预期完全一致的对象格式字符串,可手动序列化 let outputStr = '{' + Array.from(sortedResult).map(([k, v]) => `'${k}': ${v}`).join(', ') + '}'; console.log(outputStr); // 输出:{'-10': 2, '-8': 1, '1': 2, '2': 3, '6': 2, '9': 3, '10': 1}
方案2:直接使用排序后的数组
如果你的场景只是需要遍历输出升序的统计结果,不需要键值对查询能力,直接使用已经排序完成的sortedArray遍历即可,不需要转成对象:
sortedArray.forEach(([num, count]) => { console.log(`数字${num}出现次数:${count}`); })
内容的提问来源于stack exchange,提问作者takmil
相关产品推荐
相关产品推荐

