场景
最近公司要做一个日程功能,为了方便大家订会议室,所以通过这个日程功能,可以查看大家共同的空闲时间,做到自动的完成预定会议室的功能。
需求
在客户端勾选一部分人,通过请求服务器,拿到这部分人的忙碌时间(包括开会时间,请假等忙碌时间),获取到的时间则是HH:SS格式,然后在客户端上显示所有人的忙碌时间和空闲时间段。
思路
将所有人的具体时间进行转换,因为实际达到的效果是需要渲染在客户端上,所以我这边将时间直接转换成坐标,然后将所有人的忙碌时间信息放进一个集合中进行升序排序,因为如果所有人有相同的空闲时间,那必定在某两个忙碌坐标中间会有一段空白值(也就是空白区域)
代码实现
std::vector<Range> ScheduleBox::GetFreeTimes(const std::vector<Range>& busyRanges, const Range& validRange)
{
std::vector<Range> result;
std::vector<Range> items = busyRanges;
int start = validRange.top;
std::string startTime = validRange.startTime;
int end = validRange.bottom;
std::string endTime = validRange.endTime;
// 如果没有忙碌时间,就说明所有人整天都是空闲时间,直接返回当天时间
if (items.empty()) {
result.emplace_back(validRange.top, validRange.bottom, validRange.startTime, validRange.endTime);
return result;
}
while (true) {
// 升序排序忙碌时间
std::sort(items.begin(), items.end(), [](Range left, Range right) {
return left.top < right.top;
});
Range out = items[0];
// 忙碌结束时间和开始忙碌时间进行比较,如果不一致,则说明这一段是有空闲时间
if (start < out.top) {
result.emplace_back(start, out.top, startTime, out.startTime);
}
// 比较完后,需要移除比当前时间更早的时间段,因为没有再比较的意义
for (auto it = items.begin(); it != items.end();) {
if (it->top < out.bottom && it->bottom <= out.bottom) {
it = items.erase(it);
}
else {
++it;
}
}
start = out.bottom;
startTime = out.endTime;
if (items.empty()) {
break;
}
}
if (start < end) {
result.emplace_back(start, end, startTime, endTime);
}
return result;
}