在集合上使用 Switch 语句 (Swift 3)

问题描述 投票:0回答:3
enum RepeatDay : String, CustomStringConvertible {
    case Monday = "Monday"
    case Tuesday = "Tuesday"
    case Wednesday = "Wednesday"
    case Thursday = "Thursday"
    case Friday = "Friday"
    case Saturday = "Saturday"
    case Sunday = "Sunday"

    var description : String { return rawValue }

    static let allValues = [Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday]
}

以上是在我的模型中声明的。这将是一个类似的用例,例如设置闹钟时在股票时钟应用程序中选择日期。

但是下面的人抱怨!!

            guard let repeatDay = $0 else { return "" }
            switch repeatDay {
            case .Monday :
                break
            default:
                break
            }

其中

repeatDay
是一个 Set,如上面的屏幕截图所示。

在这种情况下有没有办法使用 switch 语句?欢迎任何替代方案。

swift enums switch-statement
3个回答
1
投票

您正在打开

Set<RepeatDay>
,但外壳是
RepeatDay
。 switch 语句无法知道您期望它如何处理这些不同的类型。

我怀疑您正在尝试匹配特定类型的日期组,例如工作日的日期组和周末的日期组。在这种情况下,您的 switch 的 case 语句需要是

Set<RepeatDay
,可以与提供的
Set<RepeatDay>
进行比较。

switch days {
    case [.Monday, .Tuesday, .Wednesday, .Thursday, .Friday]:
        print("Weekdays")
    case [.Saturday, .Sunday]:
        print("Weekends")
    default:
        print(days)
}

我会将这些 case 语句的集合提取为

Day
枚举的静态成员,并添加一些更多逻辑来描述连续的天数间隔。您还可以从
weekdaySymbols
DateFormatter

获取多天的区域准确名称
import Foundation

extension Array where Element: BinaryInteger {
    func isConsecutive() -> Bool {
        zip(self, self.dropFirst()).allSatisfy { current, next in
            current + 1 == next
        }
    }
}

enum Day: Int, CustomStringConvertible {
    case Sunday
    case Monday
    case Tuesday
    case Wednesday
    case Thursday
    case Friday
    case Saturday
    
    /*TODO: Note that this stores the weekdaySymbols permanently once
    the app is launched. If there is a change in locale after the app
    launch, then the days will not be updated. If this is a concern,
    this `DayNames` constant should be deleted, and all references
    to it should be changed to DateFormatter().weekdaySymbols, which
    will dynamically obtain the weekdays accurate to the current locale */
    static let DayNames: [String] = DateFormatter().weekdaySymbols
    
    public var description: String { return Day.DayNames[self.rawValue] }
    
    static let Everyday: Set<Day> = [.Sunday, .Monday, .Tuesday, .Wednesday, .Thursday, .Friday, .Saturday]
    static let Weekdays: Set<Day> = [.Monday, .Tuesday, .Wednesday, .Thursday, .Friday]
    static let Weekends: Set<Day> = [.Saturday, .Sunday]
    
    

    static func describeDays(_ days: Set<Day>) -> String {
        guard !days.isEmpty else { return "No days" }
        
        switch days { // Predefined cases
            case Day.Everyday: return "Everyday"
            case Day.Weekdays: return "Weekdays"
            case Day.Weekends: return "Weekends"
            default: break
        }
        
        let array = days.map{ $0.rawValue }.sorted()
        
        switch array {
            case _ where array.isConsecutive(): // Consecutive range of days
                let min = array.first!
                let max = array.last!
                return "\(Day(rawValue: min)!) - \(Day(rawValue: max)!)"
            default: return days.description //arbitrary days
        }
    }
}

print(Day.describeDays(Day.Everyday))
print(Day.describeDays(Day.Weekdays))
print(Day.describeDays(Day.Weekends))
print(Day.describeDays([.Monday, .Tuesday, .Wednesday, .Thursday])) // Monday - Thursday
print(Day.describeDays([.Tuesday, .Wednesday, .Thursday, .Saturday])) //[Saturday, Wednesday, Thursday, Tuesday]

您可以在此处查看实际效果。


0
投票

试试这个

guard let repeatDay = RepeatDay(rawValue: $0) else { return "" }
    switch repeatDay {
    case .Monday :
        break
    default:
        break
    }

0
投票

你的闭包中 $0 的类型不是

RepeatDay
而是
Set<RepeatDay>
,试试这个:

guard let repeatDay = $0.first else { return "" }
    switch repeatDay {
    case .Monday :
        break
    default:
        break
    }
© www.soinside.com 2019 - 2024. All rights reserved.