如何用reduce实现:查找数组中早于参考时间戳的最新对象
解决方法:无需排序查找符合条件的最大
_time对象 问题回顾
你原本使用以下依赖数组排序的代码,查找_time小于failureTime且最大的对象:
for (const elem of objs) { if (elem._time >= failureTime) {//we are one too far break; } else { temp = elem; //this will end up as the last element with timestamp before event } }
但由于数组顺序不可预测,每次排序成本高,尝试reduce失败,以下是可行方案:
方案1:用reduce一次遍历解决
这是最高效的方式,只需遍历数组一次,全程跟踪符合条件的最大_time对象:
const targetObj = objs.reduce((prev, curr) => { // 跳过_time不满足条件的元素 if (curr._time >= failureTime) return prev; // 若之前无符合条件的元素,或当前元素_time更大,则更新 return !prev || curr._time > prev._time ? curr : prev; }, null);
- 逻辑说明:不管数组顺序如何,会检查每个元素,只保留符合
_time < failureTime且_time最大的对象 - 边界处理:如果没有符合条件的元素,
targetObj会返回null,可根据需求把初始值改成{_time: -Infinity}之类的默认对象
方案2:先过滤再找最大值(更直观)
如果数组规模不大,这种写法可读性更高,先筛选出所有符合条件的元素,再从中找_time最大的:
// 第一步:过滤出_time小于failureTime的元素 const validItems = objs.filter(item => item._time < failureTime); // 第二步:从有效元素中找出_time最大的对象 const targetObj = validItems.length ? validItems.reduce((maxItem, currItem) => currItem._time > maxItem._time ? currItem : maxItem) : null;
注意:这种方法会遍历数组两次,数据量较大时不如方案1高效。
方案3:优化版手动遍历
如果你更习惯用for循环,也可以改写原来的代码,去掉排序依赖:
let targetObj = null; for (const elem of objs) { if (elem._time < failureTime) { // 仅当当前元素符合条件,且_time比已保存的更大时更新 if (!targetObj || elem._time > targetObj._time) { targetObj = elem; } } }
这个逻辑和方案1的reduce完全一致,只是用循环实现,更贴近你原本的代码风格。
内容的提问来源于stack exchange,提问作者peterandree
相关产品推荐
相关产品推荐

