You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中解决‘Index out of range’致命错误问题求助

Swift合并忙碌时段代码的错误分析与修正

你的代码存在以下几个关键问题:

  • 数组嵌套错误:eventlist的第二个元素多套了一层方括号,导致数组元素类型混乱,混入了[[String: Date]]类型的元素,后续访问会触发异常。
  • 负数索引不合法:Swift不支持像Python那样用-1直接取数组最后一个元素,busylist[-1]会直接抛出"index out of range"错误,应该用busylist.last或者busylist[busylist.count - 1]。
  • 日期字面量非法:2023-02-16 09:00:00不是Swift的合法Date写法,需要通过DateFormatter创建日期对象。
  • 强制解包风险:大量使用!强制解包,一旦字典中缺少start或end键,会直接崩溃,应该用可选绑定处理。
  • 未排序事件列表:如果事件不是按开始时间排序的,合并逻辑会失效,合并重叠时段前需要先对事件按开始时间排序。

修正后的代码:

func busyPeriod() -> [[String: Date]] {
    // 先通过DateFormatter创建合法的Date对象
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
    
    guard let event1Start = formatter.date(from: "2023-02-16 09:00:00"),
          let event1End = formatter.date(from: "2023-02-16 10:00:00"),
          let event2Start = formatter.date(from: "2023-02-16 10:00:00"),
          let event2End = formatter.date(from: "2023-02-16 10:15:00"),
          let event3Start = formatter.date(from: "2023-02-16 13:00:00"),
          let event3End = formatter.date(from: "2023-02-16 14:00:00") else {
        return []
    }
    
    var eventlist: [[String: Date]] = [
        ["start": event1Start, "end": event1End],
        ["start": event2Start, "end": event2End], // 修复嵌套错误
        ["start": event3Start, "end": event3End]
    ]
    
    // 先按开始时间排序事件列表,确保合并逻辑正确
    eventlist.sort {
        guard let start1 = $0["start"], let start2 = $1["start"] else { return false }
        return start1 < start2
    }
    
    var busylist: [[String: Date]] = []
    
    for event in eventlist {
        guard let currentStart = event["start"], let currentEnd = event["end"] else { continue }
        
        if let lastBusy = busylist.last, let lastStart = lastBusy["start"], let lastEnd = lastBusy["end"] {
            // 判断是否重叠,合并时段
            if currentStart <= lastEnd {
                let mergedStart = min(lastStart, currentStart)
                let mergedEnd = max(lastEnd, currentEnd)
                busylist[busylist.count - 1] = ["start": mergedStart, "end": mergedEnd]
            } else {
                busylist.append(event)
            }
        } else {
            // 第一个事件直接加入
            busylist.append(event)
        }
    }
    
    return busylist
}

验证输出:

调用busyPeriod()后,会得到你期望的合并结果:

[
    ["start": 2023-02-16 09:00:00 +0000, "end": 2023-02-16 10:15:00 +0000],
    ["start": 2023-02-16 13:00:00 +0000, "end": 2023-02-16 14:00:00 +0000]
]

内容的提问来源于stack exchange,提问作者Gura

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 00:50:23