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

为何基于时间字段的JavaScript数组无法按升序正确排序?

排序失效原因

你的代码排序不生效的核心问题非常明确:
Array.sort()的比较回调必须返回数字类型结果:返回值小于0时a排在b之前,大于0时b排在a之前,等于0时两者相对位置不变。但你的代码里对moment实例调用.format('hh:mm a')得到的是字符串类型值,两个字符串直接做算术减法的结果永远是NaN,sort回调返回NaN时排序逻辑完全不可预期,自然得不到正确的升序结果。
你搜到的同类用format返回值做减法的实现本身就是错误用法,完全违背了moment和Array.sort的API设计规则。

修复方案

基于moment的正确写法

比较moment时间直接取时间戳做数字差值即可,不需要做格式化操作。解析12小时制时间时建议显式传入格式字符串,避免解析歧义:

let myVar = [{time: "3:00 pm", name: "Landon"},{time: "5:20 pm", name: "Amanda"},{time: "4:00 pm", name: "Kid"}]
const sortedArray  = myVar.sort((a,b) => {
  // 显式指定解析格式,通过valueOf拿到毫秒级时间戳做数字比较
  return moment(a.time, 'hh:mm a').valueOf() - moment(b.time, 'hh:mm a').valueOf()
})
console.log(sortedArray)

无依赖原生JS写法

如果不想引入moment库,也可以手动把12小时制时间转为当日累计分钟数做比较,逻辑轻量且无兼容问题:

const sortedArray = myVar.sort((a, b) => {
  const timeToMinutes = (timeStr) => {
    const [clock, period] = timeStr.split(' ')
    let [hour, minute] = clock.split(':').map(Number)
    // 12小时制转24小时制
    if (period.toLowerCase() === 'pm' && hour !== 12) hour += 12
    if (period.toLowerCase() === 'am' && hour === 12) hour = 0
    return hour * 60 + minute
  }
  return timeToMinutes(a.time) - timeToMinutes(b.time)
})

两种写法运行后都会得到正确的升序结果:3:00 pm(Landon)→ 4:00 pm(Kid)→ 5:20 pm(Amanda)

内容的提问来源于stack exchange,提问作者WeAreHawk09

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 05:06:05