如何通过reduce按title含指定子串过滤数组对象并计算软件经验
现有代码核心问题
- 经验计算未基于过滤后的职位数据取值,直接引用全量
positionsArray的首尾时间,导致未命中匹配规则的职位被纳入计算,结果失真 - 时间差计算逻辑错误:原有嵌套乘除1000的计算会将毫秒差换算后的天数缩小1e6倍,最终结果完全偏离实际值
- 循环逻辑冗余:在
forEach遍历每个职位时,只要命中一次匹配规则就重复计算、覆盖经验值,存在无意义的性能消耗 - 匹配逻辑无大小写兼容:如果职位title包含大写的匹配关键词(如
QA Engineer),直接用小写子串做includes匹配会出现漏判
基于reduce的修正实现
calculateSoftwareExperience: async function () { // 提前将匹配规则转为小写,避免大小写差异导致的漏判 const lowerTitlesIncluded = titlesIncluded.map(item => item.toLowerCase()); fileToCurate.forEach(candidate => { const positionsArray = Array.isArray(candidate.softwareIndustryPositions) ? candidate.softwareIndustryPositions : []; // 用reduce直接过滤出符合规则的职位,剔除无效率对象 const validPositions = positionsArray.reduce((acc, position) => { const currentTitle = position.title?.toLowerCase() ?? ''; const isMatch = lowerTitlesIncluded.some(keyword => currentTitle.includes(keyword)); // 仅将命中规则的职位累积到结果数组 return isMatch ? [...acc, position] : acc; }, []); // 基于有效职位数组计算经验值 if (!validPositions.length) { candidate.softwareIndustryExp = 0; return; } // 原数组为时间倒序排列:首元素是最新任职,尾元素是最早任职 const earliestTime = new Date(validPositions.at(-1).from).getTime(); const latestTime = new Date(validPositions[0].to).getTime(); const totalDays = (latestTime - earliestTime) / (1000 * 60 * 60 * 24); // 保留原有按31天/月的粗略统计口径 candidate.softwareIndustryExp = Math.floor(totalDays / 31); }); }
实现逻辑说明
- 过滤逻辑完全依托
reduce完成,无额外filter步骤,匹配用reduce转换数组、剔除无效对象的需求 - 时间取值仅从过滤后的
validPositions数组中获取,彻底解决原有代码未过滤就取全量数组时间的问题 - 补充了数组类型判断,避免非数组格式的
softwareIndustryPositions导致的运行报错 - 匹配环节兼容大小写差异,同时做了空值兜底(防止title为undefined时报错)
- 计算流程从原来的逐职位循环重复赋值,简化为一次过滤、一次取值计算,减少无意义的重复操作
内容的提问来源于stack exchange,提问作者johnsmith
相关产品推荐
相关产品推荐

