近日,接到个紧急需求,考勤员给员工排班,可是这个员工当天有请假时间段,有休息时间段,有用餐时间段。因此这个员工当天的排班时长应该是 时长 = 班别时长 - 请假时长 - 用餐时长 - 休息时长
。es6
针对这个需求,咱们有这样一批数据:数组
var schedule = { beginTime: '2019-05-24 20:00', endTime: '2019-05-25 07:00' } var leaveTime = [{ beginTime: '2019-05-24 18:00', endTime: '2019-05-25 00:00' }] var mealTime = [{ beginTime: '2019-05-24 23:00', endTime: '2019-05-25 01:00' }] var breakTime = [{ beginTime: '2019-05-25 00:00', endTime: '2019-05-25 02:00' }, { beginTime: '2019-05-25 04:00', endTime: '2019-05-25 06:00' }]
因为请假、用餐时间段能够在排班区间外(😣不要问为何能够,这是需求️),因此咱们对于请假和用餐必需要先处理一次。咱们首先分析一下,这里用请假举例。spa
针对以上结论,代码逻辑以下:code
function getExceptTimePeriodInSchedule(schedule, timePeriod){ const BT = schedule.beginTime; const ET = schedule.endTime; let exceptTimePeriod = []; _.each(timePeriod, timeRange=>{ let { beginTime, endTime } = timeRange; if(beginTime < BT && endTime >= BT && endTime < ET){ exceptTimePeriod.push({ beginTime: BT, endTime }); }else if(beginTime >= BT && beginTime < ET && endTime <= ET){ exceptTimePeriod.push({ beginTime, endTime }); }else if(beginTime >= BT && beginTime < ET && endTime > ET){ exceptTimePeriod.push({ beginTime, endTime: ET }); }else if(beginTime < BT && endTime > ET){ exceptTimePeriod.push({ beginTime: BT, endTime: ET }); } }) return exceptTimePeriod; }
根据 getExceptTimePeriodInSchedule 方法,咱们已经获取到全部在排班区间内的排班数据。这个时候,咱们就须要处理请假、休息、用餐交叉问题。看见三个数组,想一想都有点发慌,首先脑海中瞬间决定不能经过遍历每个数组来解决交叉问题。咱们先画个图再仔细思考。排序
filter
、Set
和 reduce
等方法,若是不知道的能够看How to Remove Array Duplicates in ES6。针对于咱们遇到的难点,咱们打算用 reduce
来解决。对应代码以下:rem
function getExceptTimePeriod(timePeriod){ timePeriod = _.sortBy(timePeriod, ['beginTime', 'endTime']); timePeriod = _.reduce( timePeriod, (result, item) => { let last = result[result.length - 1]; if (last) { if (item.beginTime <= last.endTime && item.beginTime >= last.beginTime && item.endTime > last.endTime) { last.endTime = item.endTime; } else { result.push(item); } return result; } else { result.push(item); return result; } }, [] ); return timePeriod; };
经过上面两个关键方法,咱们就能够获取到不交叉重复的时间区间。欢迎小伙伴提出改进和其余解决方案,若是以为这篇文章对你有所帮助,还请多多支持 🌹。get