如何优化Swift中的getRange()函数以支持非连续日期场景?
优化Swift的getRange()函数处理非连续日期场景
首先需要给Days枚举添加顺序标识,这样才能判断日期是否连续。我们可以给它添加Int类型的rawValue并遵循CaseIterable协议:
enum Days: Int, CaseIterable, CustomStringConvertible { case Monday = 1, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday // 自定义字符串输出,避免默认枚举名的格式问题 var description: String { switch self { case .Monday: return "Monday" case .Tuesday: return "Tuesday" case .Wednesday: return "Wednesday" case .Thursday: return "Thursday" case .Friday: return "Friday" case .Saturday: return "Saturday" case .Sunday: return "Sunday" } } }
接下来重写getRange()相关函数,核心逻辑是将非连续的日期数组分割成连续区间,再根据需求生成不同格式的输出:
实现方案1:完整输出所有连续区间
适用于需要展示全部日期范围的场景,比如[.Monday, .Tuesday, .Saturday, .Sunday]输出Monday to Tuesday and Saturday to Sunday,[.Monday, .Saturday, .Sunday]输出Monday and Saturday to Sunday。
struct ChildView: View { let car: Car var body: some View { VStack { Text(getFullRangeString()) } } private func getFullRangeString() -> String { guard !car.rent.isEmpty else { return "Empty" } // 1. 将日期数组按连续区间分组 var ranges: [[Days]] = [] var currentRange: [Days] = [car.rent[0]] for day in car.rent.dropFirst() { if day.rawValue == currentRange.last!.rawValue + 1 { currentRange.append(day) } else { ranges.append(currentRange) currentRange = [day] } } ranges.append(currentRange) // 2. 将每个区间转换为字符串 let rangeStrings = ranges.map { range in range.count == 1 ? range[0].description : "\(range.first!.description) to \(range.last!.description)" } // 3. 拼接字符串,最后一个区间用"and"连接 switch rangeStrings.count { case 0: return "Empty" case 1: return rangeStrings[0] default: let allButLast = rangeStrings.dropLast().joined(separator: ", ") return "\(allButLast) and \(rangeStrings.last!)" } } }
实现方案2:简化输出(显示首个区间+“and others”)
适用于只需要展示主要区间、其余简化的场景,比如[.Monday, .Tuesday, .Saturday, .Sunday]输出Monday to Tuesday and others,[.Monday, .Saturday, .Sunday]输出Monday and others。
private func getSimplifiedRangeString() -> String { guard !car.rent.isEmpty else { return "Empty" } // 生成首个区间的字符串 var firstRange: [Days] = [car.rent[0]] for day in car.rent.dropFirst() { if day.rawValue == firstRange.last!.rawValue + 1 { firstRange.append(day) } else { break } } let firstRangeString = firstRange.count == 1 ? firstRange[0].description : "\(firstRange.first!.description) to \(firstRange.last!.description)" // 判断是否有其他非连续区间 let hasOtherRanges = car.rent.count > firstRange.count return hasOtherRanges ? "\(firstRangeString) and others" : firstRangeString }
实现方案3:仅显示首个连续区间
适用于只关注首个区间的场景,比如[.Monday, .Tuesday, .Saturday, .Sunday]输出Monday to Tuesday,[.Monday, .Saturday, .Sunday]输出Monday。
private func getFirstRangeString() -> String { guard !car.rent.isEmpty else { return "Empty" } var firstRange: [Days] = [car.rent[0]] for day in car.rent.dropFirst() { if day.rawValue == firstRange.last!.rawValue + 1 { firstRange.append(day) } else { break } } return firstRange.count == 1 ? firstRange[0].description : "\(firstRange.first!.description) to \(firstRange.last!.description)" }
测试示例
// 测试场景1:非连续双区间 let car1 = Car(rent: [.Monday, .Tuesday, .Saturday, .Sunday]) // getFullRangeString() → "Monday to Tuesday and Saturday to Sunday" // getSimplifiedRangeString() → "Monday to Tuesday and others" // getFirstRangeString() → "Monday to Tuesday" // 测试场景2:单个零散日期+连续区间 let car2 = Car(rent: [.Monday, .Saturday, .Sunday]) // getFullRangeString() → "Monday and Saturday to Sunday" // getSimplifiedRangeString() → "Monday and others" // getFirstRangeString() → "Monday" // 测试场景3:空数组 let car3 = Car(rent: []) // 所有函数返回 "Empty" // 测试场景4:单个日期 let car4 = Car(rent: [.Wednesday]) // 所有函数返回 "Wednesday"
以上方案均无需修改现有Car结构体,直接通过优化函数即可适配所有场景,你可以根据业务需求选择对应的实现方式。
内容的提问来源于stack exchange,提问作者Alexnnd
相关产品推荐
相关产品推荐

