求优雅的JavaScript实现:按元素出现次数分组数组元素
优雅实现数组元素按出现次数分组
需求是把类似 ['a', 'b', 'c', 'd', 'a', 'c'] 的数组,转换成以出现次数为键、对应元素数组为值的对象,示例输出:
{ 2: ['a', 'c'], 1: ['b', 'd'], }
目前常见的方案只能生成元素对应次数的映射,比如:
{ 'a': 2, 'b': 1, 'c': 2, 'd': 1 }
你自己的实现虽然能达到效果,但每次用filter统计次数会导致时间复杂度达到O(n²),不够高效也不够优雅。这里提供更简洁高效的实现方式:
实现思路
- 先遍历一次数组,统计每个元素的出现次数
- 再基于统计结果,按次数分组生成目标对象
完整代码
const arr = ['a', 'b', 'c', 'd', 'a', 'c']; // 第一步:统计元素出现次数 const countMap = arr.reduce((acc, curr) => { acc[curr] = (acc[curr] || 0) + 1; return acc; }, {}); // 第二步:按次数分组生成目标对象 const result = Object.entries(countMap).reduce((acc, [key, count]) => { // 若当前次数对应的数组不存在,先初始化空数组 acc[count] = acc[count] || []; acc[count].push(key); return acc; }, {}); console.log(result); // 输出:{ '1': ['b', 'd'], '2': ['a', 'c'] }
优势说明
- 仅需两次线性遍历(时间复杂度O(n)),比原实现的O(n²)高效很多
- 用
reduce链式处理,逻辑连贯简洁 - 无需额外去重操作,统计次数的过程自然处理了重复元素
内容的提问来源于stack exchange,提问作者lioness99a
相关产品推荐
相关产品推荐

