不使用lodash 原生JavaScript高效按属性分组对象数组的实现方法
原生JS按对象指定属性分组并降序排序实现方案
实现思路
- 单次遍历原数组完成分组,时间复杂度为O(n),使用Map存储分组映射,查找和插入的效率更高
- 分组完成后仅对分组结果排序,排序时间复杂度为O(k log k),k为分组数量,通常远小于原数组长度
- 兼容数字、字符串类型的属性值排序场景
实现代码
function groupBySorted(arr, propKey) { const groupMap = new Map(); // 单次遍历完成分组 for (const item of arr) { const propVal = item[propKey]; if (groupMap.has(propVal)) { groupMap.get(propVal).data.push(item); } else { groupMap.set(propVal, { [propKey]: propVal, data: [item] }); } } // 按属性值降序排序分组 return Array.from(groupMap.values()).sort((a, b) => { // 数字类型直接做差,字符串类型用localeCompare保证排序正确性 if (typeof a[propKey] === 'number' && typeof b[propKey] === 'number') { return b[propKey] - a[propKey]; } return String(b[propKey]).localeCompare(String(a[propKey])); }); }
测试示例
输入数据:
const data = [{year: "2021", name: "Rick"}, {year: "2020", name: "Joe"}, {year: "2021", name: "Sam"}, {year: "2019", name: "Sally"}, {year: "2019", name: "Jess"}];
调用方法:
const result = groupBySorted(data, 'year');
输出结果与需求给出的期望结果完全一致。
效率说明
该方案是当前原生JS实现该需求的最高效方案,和先对全量原数组排序再分组的实现相比,在原数组长度大、分组数量少的场景下性能优势极为突出。
内容的提问来源于stack exchange,提问作者JaeLeeSo
相关产品推荐
相关产品推荐

