如何对Discord机器人等级系统的ranks对象按等级值降序排序?
按等级数值对JS对象降序排序的实现
你之前转列表调用sort没得到预期结果,通常是没有正确绑定键值对应关系,或是重组对象时没有利用好JS规范定义的键序规则,可直接用三步标准流程实现需求:
- 用
Object.entries()把原对象转为[用户名, 等级]格式的二维数组,全程保留用户名和对应等级的绑定关系,不会错位 - 对二维数组按等级值做降序排序
- 把排序完成的数组重新组装为对象
完整可运行代码
// 原始等级对象 let ranks = { "Joe": 1, "Mary": 6, "Johnson": 4 } // 执行排序,生成新的有序对象 const sortedRanks = Object.fromEntries( Object.entries(ranks).sort((a, b) => b[1] - a[1]) ) console.log(sortedRanks) // 输出预期效果:{ Mary: 6, Johnson: 4, Joe: 1 }
关键说明
- 排序顺序的可靠性:ES2015之后的JS规范明确规定,字符串类型键的普通对象会严格按照键的插入顺序保留遍历顺序,
Object.fromEntries会严格按照传入的数组顺序插入键值对。目前跑Discord机器人常用的Node.js 14+、16+、18+版本都完全支持这个行为,不会出现排序后顺序错乱的问题。 - 常见踩坑点:
- 单独取
Object.keys()或Object.values()转数组排序,会直接导致用户名和等级的对应关系错位 sort的回调参数顺序写反:如果写成(a, b) => a[1] - b[1],得到的是从低到高的升序结果,降序排序需要交换a、b的位置- 仅对原对象的键数组做排序,没有把排序后的键值对重新写入对象,自然无法得到预期的顺序
- 单独取
老旧运行环境兜底写法
如果遇到不支持Object.fromEntries的极旧Node.js版本,可手动通过reduce方法重组对象,效果完全一致:
const sortedRanks = Object.entries(ranks) .sort((a, b) => b[1] - a[1]) .reduce((acc, [name, level]) => { acc[name] = level return acc }, {})
内容的提问来源于stack exchange,提问作者Michael Manders
相关产品推荐
相关产品推荐

