You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 20:36:05