如何利用Moment.js在对象数组中比较日期时间并标记最新数据
使用Moment.js结合map/reduce标记最新数据
看起来你已经找对了方向,但原来的循环写法有几个小问题(比如数组越界、属性赋值错误),而且直接比较时间字符串虽然在ISO格式下能工作,但用Moment.js处理时间会更稳妥,尤其是面对非标准格式的时间时。
下面给你两种简洁的实现方式,都是基于Moment.js的:
方法一:先找最新时间,再批量标记(map + reduce)
这种方式逻辑清晰,先通过reduce找出所有数据里最新的updated_at,再用map遍历每条数据做标记:
// 假设已经引入了Moment.js(可以通过script标签或npm包引入) const data = [{ "is_latest": "", "created_at": "2021-09-21T21:24:05.000Z", "updated_at": "2021-09-21T17:53:29.000Z" }, { "is_latest": "", "created_at": "2021-09-22T21:24:05.000Z", "updated_at": "2021-09-22T17:53:29.000Z" }, { "is_latest": "", "created_at": "2021-09-29T21:24:05.000Z", "updated_at": "2021-09-29T17:53:29.000Z" }]; // 第一步:用reduce找到最新的updated_at时间对象 const latestTime = data.reduce((maxTime, item) => { const currentMoment = moment(item.updated_at); // 比较当前时间是否比已记录的最大时间晚,是则更新 return currentMoment.isAfter(maxTime) ? currentMoment : maxTime; }, moment.min()); // 初始值设为Moment能表示的最小时间 // 第二步:用map遍历数据,标记每条的is_latest const markedData = data.map(item => ({ ...item, // 判断当前item的updated_at是否和最新时间完全一致 is_latest: moment(item.updated_at).isSame(latestTime) })); console.log(markedData);
这段代码会输出你预期的结果(is_latest为布尔值,如果你需要字符串格式的"true"/"false",可以改成is_latest: moment(item.updated_at).isSame(latestTime) ? "true" : "false")
方法二:单次遍历完成(reduce)
如果你想只用一次遍历就完成,可以用reduce同时追踪最新时间和构建结果数组:
const markedData = data.reduce((acc, item) => { const currentMoment = moment(item.updated_at); // 第一次遍历或者当前时间比已记录的最新时间晚 if (!acc.latestTime || currentMoment.isAfter(acc.latestTime)) { // 先把之前标记为true的项改成false acc.result = acc.result.map(i => ({...i, is_latest: false})); // 添加当前项,标记为true acc.result.push({...item, is_latest: true}); // 更新最新时间 acc.latestTime = currentMoment; } else { // 当前时间不是最新,标记为false acc.result.push({...item, is_latest: false}); } return acc; }, { result: [], latestTime: null }).result;
这种方式只遍历一次数据,但逻辑稍复杂一点,适合数据量较大的场景。
你原来代码的问题说明
- 数组越界:循环中
i+1会在i为最后一个元素时访问data[i+1](即undefined),导致报错; - 属性赋值错误:你给
data.is_latest赋值,而不是当前遍历的data[i].is_latest; - 时间比较的可靠性:直接比较ISO格式的字符串虽然可行,但如果遇到非标准格式的时间就会出错,用Moment.js的时间对象比较更可靠。
内容的提问来源于stack exchange,提问作者kumar
相关产品推荐
相关产品推荐

