如何在JavaScript中条件合并员工考勤的daily_data与time_off数组?
问题原因分析
你的代码逻辑完全偏离需求,核心错误点:
- 错误使用
map和条件判断:data_daily.map会遍历每条打卡记录,但你直接判断time_off.length>0就返回整个time_off数组的展开对象,导致所有打卡记录被错误替换成休假数据结构。 - 缺失用户存在性校验:完全没有实现「判断
time_off用户是否在data_daily中存在」的逻辑,更没有保留打卡数据、补充休假数据的核心逻辑。
正确实现代码
let data_daily = [{ "id": 6583194952, "date": "2022-10-31", "user_id": 1171637, "project_id": 2082652, "task_id": 111873721, "keyboard": 3891, "mouse": 8714, "overall": 11875, "tracked": 29494, "input_tracked": 29494, "manual": 0, "idle": 0, "resumed": 0, "billable": 17700, "created_at": "2022-10-31T14:14:05.300434Z", "updated_at": "2022-10-31T11:02:04.105898Z" }, { "id": 6583205067, "date": "2022-10-31", "user_id": 1762437, "project_id": 2082652, "task_id": 111407896, "keyboard": 3843, "mouse": 13066, "overall": 15760, "tracked": 29275, "input_tracked": 29275, "manual": 0, "idle": 0, "resumed": 0, "billable": 29275, "created_at": "2022-10-31T14:15:54.284572Z", "updated_at": "2022-10-31T11:01:52.894533Z" } ] let time_off = [{ "user_id": 957963, "date_start": "2022-10-31", "date_end": "2022-11-05", "rol": "DEV", "reason": "Permiso", "created_at": "2022-10-31T15:46:42+00:00", "kpi": "permission", "activity": 60, "tracked": 4, "user": { "user_id": 957963, "name": "Isaac xxx", "email": "isaac.correo@c.com", "status": "active", "created_at": "2022-10-31T06:36:42.898255Z", "updated_at": "2022-10-31T13:59:08.095330Z", "daily_hours": 8, "username": "ISAAC XXX", "time_work": "FULLTIME", "job_position": "Junior" } }, { "user_id": 957706, "date_start": "2022-10-31", "date_end": "2022-10-31", "rol": "DEV", "reason": "permission", "created_at": "2022-10-31T06:18:25+00:00", "kpi": "permission", "activity": 60, "tracked": 4, "user": { "user_id": 957706, "name": "Cesar xxxx", "email": "cesarz@c.com", "status": "active", "created_at": "2022-10-31T19:41:27.759263Z", "updated_at": "2022-10-31T15:20:46.296994Z", "daily_hours": 8, "username": "CESAR XXXX", "time_work": "FULLTIME", "job_position": "Junior " } } ] // 1. 用user_id建立打卡数据映射,快速判断用户是否存在 const dailyUserMap = new Map(); data_daily.forEach(item => { dailyUserMap.set(item.user_id, item); }); // 2. 过滤并转换休假数据:只保留不在打卡数据中的用户,统一格式 const timeOffRecords = time_off .filter(offItem => !dailyUserMap.has(offItem.user_id)) .map(offItem => { const dailyHoursInSeconds = offItem.user.daily_hours * 3600; return { id: Date.now() + offItem.user_id, // 生成唯一id,可按需调整 date: offItem.date_start, user_id: offItem.user_id, project_id: null, task_id: null, keyboard: 0, mouse: 0, overall: 0, tracked: dailyHoursInSeconds, input_tracked: 0, manual: 0, idle: 0, resumed: 0, billable: 0, created_at: offItem.created_at, updated_at: offItem.created_at, // 可保留休假相关标识字段 leave_reason: offItem.reason, leave_type: offItem.kpi }; }); // 3. 合并打卡数据和处理后的休假数据 const result = [...data_daily, ...timeOffRecords]; console.log(result);
核心逻辑说明
- 快速查找用户:用
Map存储打卡数据的user_id与对应记录,判断用户是否存在的时间复杂度为O(1),比循环遍历更高效。 - 统一数据格式:将休假记录转换为与打卡数据完全一致的字段结构,补全缺失字段的默认值,同时可保留休假专属标识字段。
- 合并结果:用扩展运算符将原始打卡数据和处理后的休假数据合并,得到包含所有用户当日记录的最终数组。
内容的提问来源于stack exchange,提问作者Izlia
相关产品推荐
相关产品推荐

