Swift 4 Decodable: как сопоставить несколько значений с одним значением перечисления?

поэтому я пытаюсь использовать Decodable для декодирования поля в этот формат:

enum ClothingType: String, Decodable {
    case SHIRT
    case PANTS
    case SHOES
    case HAT
}

Но мой JSON возвращает следующие значения в кавычках, и я хочу, чтобы они были сопоставлены с одним из четырех приведенных выше типов:

"T_SHIRT" и "LONG_SLEEVE_SHIRT" -> SHIRT

"JEANS" и "SHORTS" -> PANTS

"SNEAKERS" и "SANDALS" -> SHOES

"BASEBALL_CAP" и "WINTER_HAT" -> HAT

Как мне добиться этого с помощью Decodable? Спасибо!


person Kevin    schedule 29.03.2018    source источник
comment
Добавьте свой настоящий JSON   -  person nayem    schedule 30.03.2018


Ответы (2)


Вместо этого я бы рекомендовал сделать что-то вроде этого:

enum ClothingType: String, Codable {
    case tShirt = "T_SHIRT"
    case longSleepShirt = "LONG_SLEEVE_SHIRT"
    case jeans = "JEANS"
    case shorts = "SHORTS"
    case sneakers = "SNEAKERS"
    case sandals = "SANDALS"
    case baseballCap = "BASEBALL_CAP"
    case winterHat = "WINTER_HAT"

    var subType: SubType {
        switch self {
        case .tShirt, .longSleepShirt:
            return .shirt
        case .jeans, .shorts:
            return .pants
        case .sneakers, .sandals:
            return .shoes
        case .baseballCap, .winterHat:
            return .hat
        }
    }

    enum SubType {
        case shirt
        case pants
        case shoes
        case hat
    }
}

Это позволяет вам сохранить вашу закодированную структуру данных в соответствии с тем, как она будет выглядеть в конечном итоге, позволяя вам сохранить соглашения об именах и определить, какие аспекты важны для вас.

person GetSwifty    schedule 29.03.2018
comment
return SubType.shirt является избыточным. return .shirt - person Leo Dabus; 30.03.2018
comment
Не понимал, что это работает для внутренних перечислений. Хороший улов! - person GetSwifty; 30.03.2018

На этой неделе я узнал, что Decodable действительно гибкий, вы можете сделать что-то вроде:

enum ClothingType: Decodable {
    case shirt
    case pants
    case shoes
    case hat

    private enum RawClothingType: String, Decodable {
        case tShirt = "T_SHIRT"
        case longSleepShirt = "LONG_SLEEVE_SHIRT"
        case jeans = "JEANS"
        case shorts = "SHORTS"
        case sneakers = "SNEAKERS"
        case sandals = "SANDALS"
        case baseballCap = "BASEBALL_CAP"
        case winterHat = "WINTER_HAT"
    }

    init(from decoder: Decoder) throws {
        let rawClothingType = try RawClothingType(from: decoder)

        switch rawClothingType {
        case .tShirt, .longSleepShirt: self = .shirt
        case .jeans, .shorts: self = .pants
        case .sneakers, .sandals: self = .shoes
        case .baseballCap, .winterHat: self = .hat
        }
    }
}

Это скрывает исходный тип одежды (футболка, джинсы и т. д.), поэтому используйте его, если хотите.

person Jenny    schedule 31.03.2018