如何检测Map[String, List[(String, String)]]格式营业时间的重叠时段?
检查营业时间Map中的重叠时段
我有一个类型为Map[String, List[(String, String)]]的每日营业时间列表,键为星期几,列表元素包含open_from和open_to,示例如下:
Map( MONDAY -> List(("08:00:00", "12:00:00"), ("13:00:00", "16:00:00")), TUESDAY -> List(("09:00:00", "12:00:00"), ("13:00:00", "16:00:00")), ... )
需要检查以下条件以判断是否存在重叠时段:
- 每个时段的
open_to必须大于open_from; - 若某一天的时段列表元素多于1个,前一个元素的
open_to必须小于后一个元素的open_from。
需返回布尔值表示该Map中是否存在重叠时段。我尝试用foldLeft比较列表中的下一个元素,但不确定如何返回布尔值,请问该如何实现?
解决方案
实现思路
- 先将字符串格式的时间转换为可直接比较的时间对象(比如
LocalTime),避免字符串比较的逻辑误差; - 对每一天的时段列表做两项校验:单个时段的合法性、相邻时段是否重叠;
- 遍历整个Map,只要有任意一天不符合规则,就返回
true(表示存在重叠/非法时段),否则返回false。
Scala代码实现
import java.time.LocalTime import java.time.format.DateTimeFormatter def hasOverlappingHours(hoursMap: Map[String, List[(String, String)]]): Boolean = { val timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss") // 校验单天的时段是否合法或存在重叠 def checkDaySlots(slots: List[(String, String)]): Boolean = { slots match { case Nil => false // 无时段不算异常 case _ => // 转换所有时段为LocalTime,并同步检查单个时段合法性 val parsedSlots = slots.map { case (fromStr, toStr) => val from = LocalTime.parse(fromStr, timeFormatter) val to = LocalTime.parse(toStr, timeFormatter) (from, to) } // 检查是否有单个时段的结束时间不晚于开始时间 val hasInvalidSingleSlot = parsedSlots.exists { case (from, to) => !to.isAfter(from) } // 检查相邻时段是否重叠(前一个的结束时间不早于后一个的开始时间) val hasAdjacentOverlap = parsedSlots.sliding(2).exists { case List((_, prevTo), (nextFrom, _)) => !nextFrom.isAfter(prevTo) case _ => false } hasInvalidSingleSlot || hasAdjacentOverlap } } // 遍历所有日期,只要有一天存在异常就返回true hoursMap.values.exists(checkDaySlots) }
代码说明
- 使用
LocalTime处理时间,能直接通过isAfter等方法准确判断时间先后; sliding(2)方法可以便捷获取相邻的两个时段,简化重叠校验逻辑;exists方法会在找到第一个异常情况时立即返回,无需遍历全部数据,提升效率;- 最终返回
true代表存在重叠或非法时段,false代表所有时段都符合规则。
内容的提问来源于stack exchange,提问作者SRN
相关产品推荐
相关产品推荐

