如何用Moment.js对数组按新旧时间排序?代码为何失效?
问题分析与解决方案
你的排序代码失效的核心问题在于你试图对moment().format('L')返回的字符串做减法运算,而字符串之间的减法操作会得到NaN,这会导致sort函数无法正确判断元素顺序,自然达不到预期的排序效果。
为什么会出错?
当你调用moment(prev).format('L')时,它返回的是本地化的日期字符串(比如"05/22/2018")。JavaScript中字符串用-运算时,会尝试将其转换为数字,转换失败就会得到NaN。sort函数遇到NaN时无法正确比较两个元素的先后关系,排序逻辑也就彻底失效了。
正确的实现方式
你不需要把日期转换成字符串来比较,直接使用moment对象的时间戳或者moment提供的比较方法就能解决问题:
方案1:使用时间戳(数值类型)比较
if (sortFilter === 'oldest') { contactData = contactData.sort(({ created: prev }, { created: next }) => moment(prev).valueOf() - moment(next).valueOf() ); } else if (sortFilter === 'newest') { contactData = contactData.sort(({ created: prev }, { created: next }) => moment(next).valueOf() - moment(prev).valueOf() ); }
valueOf()方法会返回moment对象对应的Unix时间戳(毫秒数),这是一个纯数值,直接相减就能给sort函数提供正确的排序依据。
方案2:使用moment自带的比较方法
moment提供了isBefore、isAfter等语义化的比较方法,可读性更强:
if (sortFilter === 'oldest') { contactData = contactData.sort((a, b) => moment(a.created).isBefore(moment(b.created)) ? -1 : 1 ); } else if (sortFilter === 'newest') { contactData = contactData.sort((a, b) => moment(a.created).isAfter(moment(b.created)) ? -1 : 1 ); }
额外提示
注意:Array.sort()是原地排序,会直接修改原数组。如果你不想破坏原数组的结构,可以先创建数组副本再排序:
contactData = [...contactData].sort(/* 排序逻辑 */);
内容的提问来源于stack exchange,提问作者gpbaculio
相关产品推荐
相关产品推荐

