JavaScript数组大小写不敏感通用排序:日期处理需特殊逻辑吗?
关于Lodash orderBy日期排序的特殊处理建议
你担心的点完全正确——日期类型确实需要单独做特殊处理,不然现有代码的排序逻辑很可能会出问题,我来给你拆解原因和解决方案:
为什么现有代码处理不了日期?
你的当前逻辑只区分了数值和字符串:
- 如果是
Date对象,$.isNumeric()会返回false,会走到toLowerCase()调用,但Date对象调用这个方法会直接转成带格式的字符串(比如"Wed May 20 2024 12:00:00 GMT+0800 (中国标准时间)"),这样排序会变成字符串字典序,完全不符合时间先后的预期。 - 如果是日期格式的字符串(比如
"12/31/2023"这种非ISO格式),虽然是字符串,但直接toLowerCase()后按字典序排序,会出现"12/31/2023"排在"01/01/2024"前面的错误结果。
修改后的实现代码
我们需要在逻辑里加入日期的判断和处理,优先把日期转成可用于排序的时间戳:
const sorted = _.orderBy(this, function (o) { const value = o[column]; // 优先处理日期:判断是否为有效日期(包括Date对象和合法日期字符串) const dateCandidate = new Date(value); if (!isNaN(dateCandidate.getTime())) { return dateCandidate.getTime(); // 转成时间戳,用数值排序保证时间顺序 } // 处理数值类型 if ($.isNumeric(value)) { return parseFloat(value); } // 处理字符串,实现大小写不敏感排序 return typeof value === 'string' ? value.toLowerCase() : value; }, direction); this.clear(); for (let i = 0; i < sorted.length; i++) { this.push(sorted[i]); }
代码说明
- 日期判断部分:通过
new Date(value)尝试转换,再用!isNaN(dateCandidate.getTime())验证是否为有效日期,这样不管是Date实例还是合法的日期字符串(包括ISO格式、区域格式)都能被正确识别。 - 转成时间戳(
getTime())后,日期会以数值形式参与排序,完全符合时间先后的逻辑,不会出现字符串排序的错误。 - 保留了你原本的数值和字符串大小写不敏感的处理逻辑,兼容性更好。
内容的提问来源于stack exchange,提问作者Naomi
相关产品推荐
相关产品推荐

