JavaScript如何用同一个sort函数实现数组对象多字段按优先级排序
问题原因
你先后两次调用sort的写法是错误的:第二次按year排序时,会重新排列所有元素,只有两个元素year相等时才会保留第一次排序的相对顺序,大部分场景下元素year都不相同,所以第一次按type排序的结果直接被覆盖,自然无法实现同type聚合的效果。
最简实现方案
在同一个sort比较函数内按优先级判断即可:先比较type字段,当type相等时再比较year字段,代码如下:
json.sort((a, b) => { const typeA = a.type.toLowerCase() const typeB = b.type.toLowerCase() // type不相等时直接返回type的比较结果 if (typeA !== typeB) { return typeA.localeCompare(typeB) } // type相等时返回year的比较结果 return a.year - b.year })
这里用字符串内置的localeCompare方法判断字符串大小,比手动写三元判断更规范,也能兼容特殊字符、多语言的排序场景。
通用多条件排序封装
如果后续需要扩展更多排序规则,比如新增按origin排序、支持降序等需求,可以封装成通用的多条件排序函数,复用性更高:
/** * 多条件排序生成器 * @param {Array} rules 排序规则数组,每项格式为[字段名, 是否降序(可选,默认false升序)] */ const createMultiSort = (rules) => (a, b) => { for (const [field, desc = false] of rules) { let valA = a[field] let valB = b[field] // 字符串类型统一转小写后比较 if (typeof valA === 'string' && typeof valB === 'string') { valA = valA.toLowerCase() valB = valB.toLowerCase() const cmpRes = valA.localeCompare(valB) if (cmpRes !== 0) return desc ? -cmpRes : cmpRes } // 数字类型直接做差比较 const cmpRes = valA - valB if (cmpRes !== 0) return desc ? -cmpRes : cmpRes } return 0 } // 调用示例:先按type升序,再按year升序 json.sort(createMultiSort([ ['type', false], ['year', false] ]))
这种实现只需要一次排序遍历,比多次调用sort效率高很多,数组长度越大性能优势越明显。
内容的提问来源于stack exchange,提问作者markb
相关产品推荐
相关产品推荐

