如何在JavaScript对象/数组中按日期或星期排序工作条目
给员工时间表工作项按日期或星期排序的解决方案
你的timesheet目前是一个以job1、job2这类字符串为键的对象,要实现排序,先把所有工作项提取成数组,排序后按需重构对象或保留数组即可。
1. 把工作项提取为数组
用Object.values()直接从timesheet里取出所有工作项,得到一个包含所有job对象的数组:
const jobEntries = Object.values(timesheet);
2. 按day_of_week排序
day_of_week是整数类型(1-7),直接通过数值差比较就能排序。sort()会直接修改原数组,要是想保留原数据,先做个浅拷贝:
// 直接修改原数组排序 jobEntries.sort((a, b) => a.day_of_week - b.day_of_week); // 创建新数组,不改动原数据 const sortedByDay = [...jobEntries].sort((a, b) => a.day_of_week - b.day_of_week);
3. 按job_date排序
job_date是月/日格式的字符串,直接按字符串排序会出错(比如10/1会排在9/30前面),得转换成日期对象来比较:
// 直接修改原数组排序 jobEntries.sort((a, b) => { // 拆分月和日,构造统一年份的日期(同周期数据,年份不影响排序) const [aMonth, aDay] = a.job_date.split('/').map(Number); const [bMonth, bDay] = b.job_date.split('/').map(Number); const dateA = new Date(2022, aMonth - 1, aDay); const dateB = new Date(2022, bMonth - 1, bDay); return dateA - dateB; }); // 创建新数组排序 const sortedByDate = [...jobEntries].sort((a, b) => { const [aM, aD] = a.job_date.split('/').map(Number); const [bM, bD] = b.job_date.split('/').map(Number); return new Date(2022, aM - 1, aD) - new Date(2022, bM - 1, bD); });
4. 重构排序后的timesheet对象
要是需要保持原有的job1、job2键结构,遍历排序后的数组重新构建就行:
const sortedTimesheet = {}; sortedByDay.forEach((job, index) => { sortedTimesheet[`job${index + 1}`] = job; }); // 现在sortedTimesheet就是按星期排序好的时间表对象
优化建议:直接用数组收集工作项
其实你可以一开始就用数组来存工作项,而不是直接构建带jobN键的对象,后续排序会更省事:
// 替换原来的forEach逻辑,先初始化一个数组 const jobList = []; Object.entries(laborEntries).forEach(job => { const jobObj = Object(job[1]); const jobDate = new Date(job[1][4]); const isOvertime = job[1][3] === 'OverTime'; jobObj.job_date = `${jobDate.getMonth() + 1}/${jobDate.getDate() + 1}`; jobObj.day_of_week = jobDate.getDay() + 1; jobObj.wo_number = job[1][0]; jobObj.job_name = job[1][8]; jobObj.work_type_code = 'S, M, or T'; jobObj.pw_type_code = 'pw type code'; jobObj.ot_billed = isOvertime; jobObj.reg_hours = isOvertime ? 0 : Number(job[1][1]); jobObj.ot_hours = isOvertime ? Number(job[1][1]) : 0; jobObj.non_worked_hours = `${job[1][1]} -- n/w hours`; jobObj.non_worked_code = 'non-worked code'; jobObj.is_on_call = isOnCall ? '*****ON-CALL WEEK*****' : ''; // 删除无用索引 for (let i = 0; i <= 10; i++) { delete jobObj[i]; } jobList.push(jobObj); }); // 直接排序数组 jobList.sort((a,b) => a.day_of_week - b.day_of_week); // 按星期排序 // 或者按日期排序 jobList.sort((a,b) => { const [aM, aD] = a.job_date.split('/').map(Number); const [bM, bD] = b.job_date.split('/').map(Number); return new Date(2022, aM-1, aD) - new Date(2022, bM-1, bD); }); // 要是需要转换成原有的jobN结构,再遍历一次 const timesheet = {}; jobList.forEach((job, idx) => { timesheet[`job${idx+1}`] = job; });
内容的提问来源于stack exchange,提问作者mbean0302
相关产品推荐
相关产品推荐

