如何获取数组中给定日期之前的最新对象?
问题描述
我有一个简单的未排序对象数组:
const items = [ { item: 'Two', date: '2018-01-01' }, { item: 'Three', date: '2019-01-01' }, { item: 'One', date: '2022-01-01' }, { item: 'Four', date: '2021-01-01' }, ];
我想要编写一个接收单个effDate参数的函数,返回date属性早于effDate的最新item。例如,传入2020-08-22作为参数时,函数应返回item Three,因为它最接近effDate且不超过该日期。
我尝试使用reduce方法,但实现有误,它总是返回数组中的第一个对象:
const getItem = (effDate) => { return items.reduce((prev, next) => { return next.date > prev.date && next.date < effDate.date ? next : prev; }); };
那么,不自行编写完整的循环/比较函数,能否通过JavaScript内置工具实现需求?
解决方案
你的reduce代码有两个明显问题:
effDate是传入的日期字符串,不是对象,所以effDate.date会得到undefined,导致next.date < effDate.date永远不成立,逻辑分支一直走prev,自然返回第一个对象。- 判断逻辑顺序不对,应该先确认
next.date是否符合“早于effDate”的条件,再和当前的prev比较哪个日期更新。
正确的reduce实现
只需要修正这两个问题,就能用reduce完成需求:
const getItem = (effDate) => { return items.reduce((prev, next) => { // 先判断next是否符合日期条件,再比较哪个更新 if (next.date < effDate) { return prev === null || prev.date < next.date ? next : prev; } // next不符合条件,保留当前prev return prev; }, null); // 初始化prev为null,处理没有符合条件项的情况 };
如果数组中没有符合条件的项,这个函数会返回null,你可以根据需求改成对应的默认值。
另一种内置工具组合实现
如果觉得reduce逻辑绕,也可以用filter+sort的组合:
const getItem = (effDate) => { // 先过滤出所有日期早于effDate的项 const validItems = items.filter(item => item.date < effDate); // 如果没有符合条件的项,返回null或默认值 if (validItems.length === 0) return null; // 按日期降序排序,取第一个就是最新的 return validItems.sort((a, b) => b.date.localeCompare(a.date))[0]; };
注意,sort会修改原数组,这里我们对过滤后的新数组排序,不会影响原数组。另外,如果数组数据量很大,这种方式的效率不如reduce——filter和sort的时间复杂度分别是O(n)和O(n log n),而reduce是O(n)。
内容的提问来源于stack exchange,提问作者Zephyr
相关产品推荐
相关产品推荐

