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

时间:2016-11-02 04:13:41

标签: swift enums switch-statement

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
            }

screenshot

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

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

3 个答案:

答案 0 :(得分:0)

试试这个

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

答案 1 :(得分:0)

您已开启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)
}

我会提取这些案例陈述&#39;设置为Day枚举的静态成员,并添加一些逻辑来描述连续的天数间隔。您还可以从weekdaySymbols

DateFormatter获取天文区域准确名称
import Foundation

extension Array where Element: Integer {
    func isConsecutive() -> Bool {
        guard var previous = self.first else { return true }

        for current in self[1 ..< self.count] {
            if current != previous + 1 { return false }
            previous = current
        }

        return true
    }
}

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.count > 0 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]

You can see this in action, here.

答案 2 :(得分:0)

关闭时$ 0的类型不是RepeatDay而是Set<RepeatDay>,请尝试:

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