如何创建按foo键排序的Map,其值为按bar键排序的对象数组?
基于foo键创建有序Map并按bar排序分组数组
我有一个对象数组,需要基于foo键创建一个键已排序的Map,Map中每个值是对应foo的对象组成的数组,且该数组需按bar键升序排序。
输入数据:
const arr = [{'foo': 42, 'bar': 7}, {'foo': 1, 'bar': 2}, {'foo': 1, 'bar': 1}];
期望结果:
{ 1 -> [{'foo': 1, 'bar': 1}, {'foo': 1, 'bar': 2}], 42 -> [{'foo': 42, 'bar': 7}] }
简洁高效的实现方案
你当前的代码问题在于:arr.map(i => [i.foo, i])会生成重复的foo键值对,而Map会自动覆盖重复键的最后一个值,无法实现分组。下面是完整的分组+排序实现:
const result = new Map( Object.entries( arr.reduce((acc, item) => { // 按foo分组,不存在则初始化空数组 (acc[item.foo] ||= []).push(item); return acc; }, {}) ) // 将字符串键转为数字,同时对每个分组的数组按bar排序 .map(([key, group]) => [Number(key), group.sort((a, b) => a.bar - b.bar)]) // 对Map的键按数字升序排序 .sort(([a], [b]) => a - b) );
代码解释
- 分组阶段:用
reduce遍历数组,将每个对象按foo归类到对应的数组中,(acc[item.foo] ||= [])是ES6+的简洁写法,等价于判断acc[item.foo]是否存在,不存在则初始化为空数组。 - 转换与子数组排序:通过
Object.entries将分组后的对象转为键值对数组,把字符串类型的键转为数字,同时对每个分组的数组按bar键升序排序。 - Map键排序:对整个键值对数组按
foo数字升序排序,最后传入Map构造函数,得到键有序的Map。
验证结果
执行上述代码后,result的结构与期望完全一致:
- 键
1对应数组按bar从1到2排序 - 键
42对应单个对象数组 - Map的键按数字升序排列(1在前,42在后)
内容的提问来源于stack exchange,提问作者KorbenDose
相关产品推荐
相关产品推荐

