JavaScript 如何获取对象数组中日期最新的对象
JS 数组中检索日期最新对象的最优实现方案
核心思路
要找到日期字段最新的对象,本质是将可解析的日期值转换为可量化对比的时间戳,遍历数组逐次保留时间值更大的对象即可。
注意:
filter本身的设计是筛选出满足固定条件的子集,由于“全局最大日期”是需要遍历完整个数组才能确定的结果,单步遍历阶段无法判断当前值是否为全局最大,因此该场景从逻辑上就不适合用filter实现,之前尝试得不到预期结果是正常的。
推荐方案:基于reduce的单次遍历实现
这是该场景下性能最优、无副作用的标准实现,也是最适合处理这类“从数组中规约得到单个极值”的方法:
- 对比两个对象的日期时间戳,保留时间更大的那一项作为遍历的临时结果
- 必须显式传入数组第一个元素作为reduce的初始值,避免空数组、短数组的边界报错
代码示例:
// 示例数据源 const data = [ {name:"test1", date:"2019-07-21T14:25:02.816Z"}, {name:"test2", date:"2020-07-21T14:25:02.816Z"}, {name:"test3", date:"2018-07-21T14:25:02.816Z"} ] // 检索最新日期对象 const latestObject = data.reduce((currentLatest, currentItem) => { // 转换为时间戳做大小对比,避免字符串对比的格式兼容问题 return new Date(currentItem.date).getTime() > new Date(currentLatest.date).getTime() ? currentItem : currentLatest }, data[0]) console.log(latestObject) // 输出结果:{ name: 'test2', date: '2020-07-21T14:25:02.816Z' }
方案优势
- 仅需一次完整遍历,时间复杂度为O(n),相比排序实现的O(nlogn),在数据量较大时性能优势明显
- 全程不会修改原数组的顺序与内容,无副作用
- 显式传入初始值的写法,兼容空数组、单元素数组的边界场景,不会出现运行时报错
之前reduce实现失败的常见原因
- 未给reduce传入初始值:如果不传初始值,reduce第一次执行会把数组第一个元素当累加器、第二个元素当遍历值,当数组长度小于2时会直接抛出类型错误
- 直接对比日期字符串而非转换为时间戳:碰到
YYYY/M/D这类非ISO标准格式的日期字符串时,字符串的字典序对比结果会和实际时间大小不一致 - 对比逻辑写反:保留了时间戳更小的项,最终得到的是日期最旧的对象
低数据量下的备选快速实现
如果数组长度在百条以内,临时开发场景下也可以用排序的方式快速实现,但要注意必须先展开数组避免修改原数据顺序:
const latestObject = [...data].sort( (a, b) => new Date(b.date).getTime() - new Date(a.date).getTime() )[0]
这种写法的缺点是会产生额外的排序开销,且会改变数组元素的相对顺序,不适合大数组场景使用。
内容的提问来源于stack exchange,提问作者Pedro135
相关产品推荐
相关产品推荐

