JavaScript按Time字段排序对象数组结果异常如何解决
问题原因
- 你调试时手动写的对比字符串和数组里实际存储的值不一致:数组中
Time字段存的是带前导零的'01:00',你测试时写的是省略前导零的"1:00",两个字符串内容不同,比较结果自然有差异。 - JavaScript中字符串的大小比较是逐字符比对ASCII编码值,和时间、数字的大小逻辑无关:
- 比较
'01:00' > '12:00'时,第一位字符'0'(ASCII码48)小于'1'(ASCII码49),直接返回false,这就是你代码里arr[0].Time > arr[1].Time的结果来源。 - 比较
'1:00' > '12:00'时,第一位字符都是'1',比对第二位字符:':'(ASCII码58)大于'2'(ASCII码50),所以返回true。
- 比较
- 你原代码直接用字符串排序,就算格式统一,也只能实现24小时制的字符串字典序排列,和你给出的预期排序(12点时段在前,1点在后)逻辑不匹配。
你的调试截图如下:
修正方法
不要直接比较时间字符串,先把时间转成数值类型的总分钟数再做排序,从根源上避免字符串逐位比较的问题。
根据你给出的预期结果,你实际需要的是12小时制的排序规则(12点为时段起点,之后依次是1点、2点…到11点结束),实现代码如下:
arr = arr.sort(function (a, b) { // 将HH:MM格式的时间转为12小时制下的累计分钟数,用于比较 const toMinutes = (timeStr) => { let [hour, minute] = timeStr.split(':').map(Number); // 12点作为时段起点,权重设为0,比1点的权重1更小 hour = hour === 12 ? 0 : hour; return hour * 60 + minute; } return toMinutes(a.Time) - toMinutes(b.Time); });
运行上述代码后,得到的结果和你的预期完全一致:
[ { id: '7', Time: '12:00', status: 'grey' }, { id: '8', Time: '12:45', status: 'green' }, { id: '5', Time: '01:00', status: 'grey' }, ]
如果你实际需要的是普通24小时制升序排列,只需要去掉12小时制的特殊处理即可,转换函数修改为:
const toMinutes = (timeStr) => { const [hour, minute] = timeStr.split(':').map(Number); return hour * 60 + minute; }
内容的提问来源于stack exchange,提问作者code maker
相关产品推荐
相关产品推荐

