Использование enum и пользовательской строковой конвертируемости для установки текстового поля и возврата - PullRequest
0 голосов
/ 18 мая 2018

У меня есть перечисление, которое выглядит следующим образом:

enum Enum1: String, CustomStringConvertible {
    case none = "None"
    case weekly = "Weekly"
    case monthly = "Monthly"
    case quarterly = "Quarterly"
    case semiannually = "Semi-Annually"
    case annually = "Annually"

    var description: String {
        switch self {
        case .none:
            return "None"
        case .weekly:
            return "Weekly"
        case .monthly:
            return "Monthly"
        case .quarterly:
            return "Quarterly"
        case .semiannually:
            return "Semi-Annually"
        case .annually:
            return "Annually"
        }
    }

    var timePeriod: DateComponents {
        switch self {
        case .none:
            return DateComponents(day: 0)
        case .weekly:
            return DateComponents(day: 7)
        case .monthly:
            return DateComponents(month: 1)
        case .quarterly:
            return DateComponents(month: 3)
        case .semiannually:
            return DateComponents(month: 6)
        case .annually:
            return DateComponents(year: 1)
        }
    }

    var targetFrequency: Double {
        switch self {
        case .none:
            return 0.0
        case .weekly:
            return 52.0
        case .monthly:
            return 12.0
        case .quarterly:
            return 4.0
        case .semiannually:
            return 2.0
        case .annually:
            return 1.0
        }
    }
}

У меня есть pickerView, у которого есть опции нет, еженедельно, ежемесячно, ежеквартально, ..., ежегодно.Когда я выбираю это, я хочу установить переменную enumCase для соответствующего случая, используя rawValue.В конце концов я хочу вставить это значение в структуру как enumCase.targetFrequency.

Как бы я мог получить структуру и преобразовать значение targetFrequency обратно в соответствующее описание case / string.

IeЯ хочу преобразовать значение 52.0 в структуре обратно в строку «weekly», и надеялся, что смогу использовать Enum1 и мне не нужно создавать второе перечисление Enum2.

Нужно ли создавать другое перечисление, напримертак чтобы преобразовать targetFrequency обратно в соответствующий регистр?

enum Enum2: Double {
    case .none:
        return 0.0
    case .weekly:
        return 52.0
    // ....
}

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

Я предлагаю, чтобы targetFrequency было Int.

. Вы должны использовать [Int: Enum1] для хранения отображений между targetFrequency и Enum1:

static let targetFrequencyDict: [Int: Enum1] = {
    func accumulate(dict: inout [Int: Enum1], freq: Enum1) {
        dict[freq.targetFrequency] = freq
    }
    return [Enum1.none, .weekly, .monthly, .quarterly, .semiannually, .annually].reduce(into: [Int: Frequency](), accumulate)
    }()

Затем вы можете использовать targetFrequencyDict, чтобы получить желаемое значение Enum1:

Enum1.targetFrequencyDict[52] // weekly

Кроме того, чтобы уменьшить некоторые операторы switch, вы можете превратить Enum1 в структуру и иметь static let s в качестве перечисления:

struct Frequency: CustomStringConvertible {
    let description: String
    let timePeriod: DateComponents
    let targetFrequency: Int

    private init(description: String, timePeriod: DateComponents, targetFrequency: Int) {
        self.description = description
        self.timePeriod = timePeriod
        self.targetFrequency = targetFrequency
    }

    static let none = Frequency(description: "None", timePeriod: DateComponents(days: 0) , targetFrequency: 0)
    static let weekly = Frequency(description: "Weekly", timePeriod: DateComponents(days: 7) , targetFrequency: 52)
    static let monthly = Frequency(description: "Monthly", timePeriod: DateComponents(months: 1) , targetFrequency: 12)
    static let quarterly = Frequency(description: "Quarterly", timePeriod: DateComponents(months: 3) , targetFrequency: 4)
    static let semiannually = Frequency(description: "Semi-annually", timePeriod: DateComponents(months: 6) , targetFrequency: 2)
    static let annually = Frequency(description: "Annually", timePeriod: DateComponents(years: 1) , targetFrequency: 1)

    static let targetFrequencyDict: [Int: Frequency] = {
        func nextResult(dict: inout [Int: Frequency], freq: Frequency) {
            dict[freq.targetFrequency] = freq
        }
        return [Frequency.none, .weekly, .monthly, .quarterly, .semiannually, .annually].reduce(into: [Int: Frequency](), nextResult)
        }()
}
0 голосов
/ 18 мая 2018

Если я правильно понимаю ваш вопрос, вы можете просто создать инициализатор, который принимает Double в качестве параметра:

// An Int seems a lot safer though
init?(frequency: Double) {
    switch frequency {
    case 0.0:
        self = .none
    case 52.0:
        self = .weekly
    case 12.0:
        self = .monthly
    case 4.0:
        self = .quarterly
    case 2.0:
        self = .semiannually
    case 1.0:
        self = .annually
    default:
        return nil
    }
}

Примечание: не уверен (из вашего кода), почему вы хотите получить enumХотя на основе строк, но если вы это сделаете, вы можете немного упростить вашу description функцию:

var description: String {
    return rawValue
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...