【问题标题】:Using Switch statements on Sets (Swift 3)在 Set 上使用 Switch 语句(Swift 3)
【发布时间】:2016-11-02 04:13:41
【问题描述】:
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 是一个集合,如上面的屏幕截图所示。

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

【问题讨论】:

  • 给我们更多关于repeatDay声明的上下文
  • 顺便说一句,当您的枚举具有 String 绘制值时,它的默认原始值设置为案例名称,因此您可以只写 case Monday 而不是 case Monday = "Monday"
  • 哦,好的。但是,正如我所说的那样,我期望能够分别选择“星期一”、“星期二”和“工作日”,如果选择了所有五个工作日。
  • @AlexanderMomchliov,我想关于RepeatDay 没什么好解释的。我已经在上面的问题中发布了所有内容。
  • 硬编码工作日的名称是个坏主意。 DateFormatter 具有多个属性,用于根据用户的区域设置获取完整和缩写的工作日名称。

标签: swift enums switch-statement


【解决方案1】:

试试这个

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

【讨论】:

    【解决方案2】:

    您正在打开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 枚举的静态成员,并添加更多逻辑来描述连续的天数间隔。您还可以从weekdaySymbolsDateFormatter 获取天数的准确区域设置名称

    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.

    【讨论】:

      【解决方案3】:

      你的闭包中$0的类型不是RepeatDay而是Set&lt;RepeatDay&gt;,试试这个:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-21
        • 1970-01-01
        • 2014-10-06
        相关资源
        最近更新 更多