如何用JavaScript基于已有数据生成可用预约时间段数组
动态生成排除已占用时段的预约可用时间段数组
问题描述
我正在开发毕业设计的预约应用,需要实现一个功能:根据店铺的营业时间、已有的预约记录,动态生成用户可选的预约时间段数组。目前用硬编码全量时段再过滤的方式实现,想找到更灵活、可适配的方案。
需求细节:
- 店铺包含
opens(开门时间)、closes(关门时间)字段,后续需要支持不同店铺的自定义营业时间 - 每个预约有
start和end时间字段,当前默认预约时长30分钟,后续要支持自定义时长 - 需要生成从开门到关门、间隔对应时长的所有时段,自动排除已被预约占用的时段,最终结果用于用户下拉选择
示例数据:
const shop = { user: "fakeid123", title: "Barber Shop", description: "fake description", appointments: [{ customername: "Kostas", start: "12:00", end: "12:30" }, { customername: "Makis", start: "13:00", end: "13:30" }, { customername: "Kostas", start: "14:00", end: "14:30" }, { customername: "Kostas", start: "17:00", end: "17:30" } ], opens: "8:00", closes: "21:00" };
解决方案
核心思路
将时间字符串转换为分钟数(如8:00转为480分钟),方便进行数值计算和比较;基于营业时间和预约时长生成所有可能的时段,再过滤掉已被占用的时段,最后转换回时间字符串格式。
实现代码
// 工具函数:将时间字符串(如"8:00")转换为当天的分钟数 function timeToMinutes(timeStr) { const [hours, minutes] = timeStr.split(':').map(Number); return hours * 60 + minutes; } // 工具函数:将分钟数转换回时间字符串(如480转为"8:00") function minutesToTime(minutes) { const hours = Math.floor(minutes / 60); const mins = minutes % 60; return `${hours}:${mins.toString().padStart(2, '0')}`; } // 生成可用预约时段的核心函数 function generateAvailableSlots(shop, appointmentDuration = 30) { const opensInMinutes = timeToMinutes(shop.opens); const closesInMinutes = timeToMinutes(shop.closes); // 收集所有已占用时段的起始分钟数(用Set优化查找性能) const occupiedStarts = new Set(shop.appointments.map(apt => timeToMinutes(apt.start))); const availableSlots = []; // 从开门时间开始,按预约时长步进,生成所有合法时段 for (let current = opensInMinutes; current + appointmentDuration <= closesInMinutes; current += appointmentDuration) { // 若当前时段未被占用,则加入可用列表 if (!occupiedStarts.has(current)) { availableSlots.push({ start: minutesToTime(current), end: minutesToTime(current + appointmentDuration) }); } } return availableSlots; } // 使用示例 const availableSlots = generateAvailableSlots(shop); console.log(availableSlots);
扩展说明
- 适配不同预约时长:调用
generateAvailableSlots时传入第二个参数即可,例如generateAvailableSlots(shop, 45)会生成45分钟间隔的时段 - 适配不同营业时间:只要店铺对象的
opens和closes是合法的时间字符串(如"9:30"),函数会自动处理 - 性能优化:用
Set存储已占用的起始时间,将查找操作的时间复杂度从O(n)降低到O(1),适合预约记录较多的场景
内容的提问来源于stack exchange,提问作者Kwstas Greco
相关产品推荐
相关产品推荐

