如何将Underscore.js中_.groupBy的结果按键倒序排列?
如何对Underscore.js _.groupBy的结果按键倒序排序
这个需求很常见,_.groupBy本身只会帮你完成分组,不会处理键的排序问题,不过我们只需要加几步就能实现倒序排列的效果。先看一下你的场景:
原数据与默认分组结果
假设我们有这样的对象数组:
const stooges = [ {name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}, {name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60} ];
用_.groupBy(stooges, 'age')分组后,默认输出是按键的自然升序排列的对象:
{ "40": [{name: 'moe', age: 40}, {name: 'moe', age: 40}], "50": [{name: 'larry', age: 50}, {name: 'larry', age: 50}], "60": [{name: 'curly', age: 60}, {name: 'curly', age: 60}] }
期望的倒序结果
我们需要把键按数值从大到小排列,得到这样的输出:
{ "60": [{name: 'curly', age: 60}, {name: 'curly', age: 60}], "50": [{name: 'larry', age: 50}, {name: 'larry', age: 50}], "40": [{name: 'moe', age: 40}, {name: 'moe', age: 40}] }
实现方案
这里提供两种方式,你可以根据项目环境选择:
方式一:结合Underscore工具函数实现
// 1. 先完成基础分组 const grouped = _.groupBy(stooges, 'age'); // 2. 获取所有键并倒序排序(必须转成数字比较,避免字符串排序的坑) const sortedKeys = Object.keys(grouped).sort((a, b) => Number(b) - Number(a)); // 3. 用_.reduce重新构建有序对象 const reversedGrouped = _.reduce(sortedKeys, (result, key) => { result[key] = grouped[key]; return result; }, {});
方式二:用ES6+原生API更简洁
如果你的项目支持ES2019及以上,可以用Object.fromEntries简化代码:
const grouped = _.groupBy(stooges, 'age'); const reversedGrouped = Object.fromEntries( // 把对象转成键值对数组,再对键做倒序排序 Object.entries(grouped).sort(([keyA], [keyB]) => Number(keyB) - Number(keyA)) );
注意点
- 为什么要转成数字排序?因为
Object.keys返回的键是字符串类型,如果直接用字符串排序,虽然这个例子里结果没问题,但遇到"100"和"90"这种情况时,字符串排序会把"90"放在"100"前面(逐字符比较时"9"比"1"大),转成数字后排序才符合数值大小的逻辑,更严谨。 - ES2015之后,JavaScript对象的自有属性会按照插入顺序保存,所以我们重新构建的对象会保持排序后的键顺序。
内容的提问来源于stack exchange,提问作者Kishor Pawar
相关产品推荐
相关产品推荐

