
原有方法的局限性分析
在处理包含多个日期字段的复杂数据结构时,我们常常需要从中找出最早的日期。然而,如果处理逻辑不够全面,可能会导致部分日期被遗漏,从而无法得到正确的最早日期。
以下是一个简化后的原有方法示例,它旨在从一个 runout_dates 对象中找出最早的日期:
// 假设 env.STICKER_THRESH 是一个数组,例如 [30, 40, 60]
const env = {
STICKER_THRESH: [30, 40, 60]
};
const getEarliestRunout = (runout_dates = {}, dm1_type = '') => {
try {
const cur_year = new Date().getFullYear();
// 原始逻辑中用于过滤的非优先级贴纸类型
const non_priority_sticker = dm1_type == cur_year + 1 || dm1_type == cur_year ? 'dm1' : 'dm2';
return Object.entries(runout_dates).reduce((earliest, obj) => {
const key = obj[0].split('_')[0]; // 例如 'dm1', 'dm2', 'star'
const value = obj[1]; // 对应的值对象,如 { under_30: "...", under_40: "..." }
// 原始问题在于,这里只检查了 env.STICKER_THRESH[0] 对应的日期
// 并且通过 key != non_priority_sticker 进行了过滤
// 这可能导致其他阈值(如 under_40, under_60)的日期被忽略,
// 或特定类型的日期(如 star_runouts)未被全面比较。
if (value[`under_${env.STICKER_THRESH[0]}`] && key != non_priority_sticker) {
const currentDate = new Date(value[`under_${env.STICKER_THRESH[0]}`]).getTime();
return currentDate < earliest.val ? { val: currentDate, date: value[`under_${env.STICKER_THRESH[0]}`] } : { ...earliest };
}
return earliest;
}, { val: Infinity, date: '' });
} catch (e) {
console.error(`ERROR :: util.getEarliestRunout: ${e} - ${new Date()}`);
return { val: Infinity, date: '' };
}
};
// 假设的输入数据结构
const priorityRunouts = { under_30: "2024-01-10", under_40: "2024-01-15", under_60: "2024-01-20" };
const nonPriorityRunouts = { under_30: "2024-02-01", under_40: "2024-02-05", under_60: "2024-02-10" };
const starRunouts = { under_30: "2024-01-05", under_40: "2024-01-08", under_60: "2024-01-12" };
const inputRunoutDates = {
dm1_runouts: priorityRunouts,
dm2_runouts: nonPriorityRunouts,
star_runouts: starRunouts
};
// 调用示例
// const earliest_runout = getEarliestRunout(inputRunoutDates, 'some_dm1_type');
// console.log("Original method result:", earliest_runout);上述代码的问题在于:
- 比较范围受限: reduce 循环内部的条件判断 value[under_${env.STICKER_THRESH[0]}] 仅考虑了 env.STICKER_THRESH 数组中的第一个阈值(例如 under_30),而忽略了其他可能存在的阈值(如 under_40, under_60)。
- 过滤逻辑可能导致遗漏: key != non_priority_sticker 的过滤条件虽然可能满足特定业务需求,但在找出“所有日期中最早”的场景下,它可能导致某些关键日期(如 star_runouts 或特定 dm 类型)被排除在比较之外,从而无法得到全局最早日期。
- 非全面收集: reduce 的设计是逐步比较,而不是首先收集所有潜在日期,这使得在复杂对象中全面提取日期变得困难且容易出错。
优化策略:全面收集与统一比较
为了解决上述问题,一种更健壮的策略是:首先全面收集所有相关的日期字符串,将它们转换为时间戳,然后利用 Math.min 函数一次性找出最早的时间戳。
核心步骤如下:
立即学习“Java免费学习笔记(深入)”;
- 遍历所有可能的日期源: 迭代 runout_dates 对象中的每一个键值对(如 dm1_runouts, dm2_runouts, star_runouts)。
- 提取所有相关日期字符串: 对于每个日期源,遍历所有预设的阈值(如 30, 40, 60),提取对应的日期字符串(如 under_30, under_40 等)。
- 转换为时间戳并收集: 将每个有效的日期字符串转换为 Date 对象,再获取其时间戳 (getTime())。同时,过滤掉无效日期(例如,解析失败的日期会返回 NaN)。
- 找出最小值: 使用 Math.min 函数找出所有有效时间戳中的最小值。
- 返回结果: 将最早的时间戳转换回原始日期字符串或 Date 对象,并返回。
实现细节与示例代码
以下是优化后的 getEarliestRunout 函数实现:
// 假设 env.STICKER_THRESH 仍然可用,并包含所有需要检查的阈值
const env = {
STICKER










