如何按日期字符串属性对数组进行升序/降序排序?Lodash、Moment.js及原生JS尝试后未成功
如何按日期字符串属性对数组进行升序/降序排序?Lodash、Moment.js及原生JS尝试后未成功
嘿,我帮你排查下问题所在,其实核心原因是你没处理好日期字符串的解析和排序依据:
问题出在哪?
你的日期格式是DD/MM/YYYY,直接按字符串排序或者用moment().format()返回字符串再排序,本质都是字符串比较——而字符串是按字符逐个对比的,比如"31/05/2013"和"13/05/2024",字符串比较时第一个字符3>1,会把2013的日期排在2024的后面,这完全不符合实际日期顺序。另外,你用moment(o.Datum)时没指定解析格式,moment可能会把DD/MM/YYYY错误当成MM/DD/YYYY(比如13/05会被识别为无效月份),这也会导致排序混乱。
正确的解决方案
1. Lodash + Moment.js 写法
要让排序依据是日期的实际时间值,而不是字符串。你可以返回moment对象的时间戳,或者直接返回moment对象(moment支持直接比较大小),同时一定要指定解析格式:
// 升序排序 const sortedAsc = _.orderBy(testArray, (o) => moment(o.Datum, 'DD/MM/YYYY').valueOf(), ['asc']); // 降序排序 const sortedDesc = _.orderBy(testArray, (o) => moment(o.Datum, 'DD/MM/YYYY').valueOf(), ['desc']); // 更简洁的写法:直接返回moment对象,因为moment实例可直接比较 const sortedAsc = _.orderBy(testArray, (o) => moment(o.Datum, 'DD/MM/YYYY'), ['asc']);
2. 原生JS 写法(无需Lodash)
用Array.sort(),同样先把日期字符串转成可比较的时间戳或Date对象:
// 升序 testArray.sort((a, b) => { const dateA = moment(a.Datum, 'DD/MM/YYYY').valueOf(); const dateB = moment(b.Datum, 'DD/MM/YYYY').valueOf(); return dateA - dateB; }); // 降序的话反转返回值 testArray.sort((a, b) => { const dateA = moment(a.Datum, 'DD/MM/YYYY').valueOf(); const dateB = moment(b.Datum, 'DD/MM/YYYY').valueOf(); return dateB - dateA; }); // 如果不想用moment,原生Date解析的话,需要先把DD/MM/YYYY转成YYYY-MM-DD(Date能正确解析的格式) testArray.sort((a, b) => { const formatToISO = (dateStr) => { const [day, month, year] = dateStr.split('/'); return `${year}-${month}-${day}`; }; return new Date(formatToISO(a.Datum)) - new Date(formatToISO(b.Datum)); });
验证一下你的测试数组
用正确方法排序后,升序的结果应该是:ID:2(18/05/2013) → ID:3(01/05/2018) → ID:1(13/05/2024) → ID:4(31/05/2024) → ID:5(31/05/2024)
降序则反过来,同一日期的ID顺序保持原数组的相对位置(因为Lodash的orderBy是稳定排序)。
备注:内容来源于stack exchange,提问作者Tonathiu Redrovan
相关产品推荐
相关产品推荐

