Как я могу создать массив значений перечисления из массива строк - PullRequest
0 голосов
/ 18 февраля 2019

У меня есть массив строк, которые возвращаются из API.Эти строки представляют собой список доступных продуктов.

Я хотел бы использовать enum в своем приложении для представления этих данных.Я не уверен, если это возможно, однако.

enum Products: String {
    case music
    case cars
    case sport
}

Пример массива, который я получаю, может быть ["music", "cars"]

Это часть структуры, которая будет

struct CustomerState: Codable {
    var products = [Product]()
}

Я представлял себе, что могу отобразить массив и, возможно, сравнить исходные значения, однако я не могу понять, как это сделать, или это правильный / возможный подход.

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Полагаю, у вас есть json, подобный этому

let data = Data("""
{
"products" : [ "music", "cars" ]
}
""".utf8)

, тогда вы можете просто реализовать Codable в вашем перечислении

struct CustomerState: Codable {
    var products = [Products]()
}

enum Products: String, Codable {
    case music
    case cars
    case sport
}

и затем вы можете декодировать Data

do {
    let decoded = try JSONDecoder().decode(CustomerState.self, from: data)
    //print(decoded.products[0])
} catch { print(error) }

В качестве альтернативы, если json не всегда должен содержать только объявленные регистры перечисления, вы можете создать собственный инициализатор с декодером, который декодирует строковый массив и затем пытается создать значения перечисления из этих строк.Если регистр для этого необработанного значения не существует, он не добавляется

struct CustomerState: Decodable {

    var products = [Products]()

    enum CodingKeys: String, CodingKey {
        case products
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let products = try container.decode([String].self, forKey: .products)
        self.products = products.compactMap { Products(rawValue: $0) }
    }

}
0 голосов
/ 18 февраля 2019

Вы можете достичь этого путем сопоставления текущего массива строк с массивом перечислений на основе их rawValues:

let array = ["music", "cars", "tomato"]
let arrayEnum = array.map { Products(rawValue: $0) }

На данный момент имейте в виду, что arrayEnum is [Products?] содержит 3 элемента, потому что отображение строки "tomato" дает nil.Чтобы избавиться от nils, вы можете использовать compactMap:

let array = ["music", "cars", "tomato"]

let arrayEnum = array.compactMap { Products(rawValue: $0) }
print(arrayEnum)

Теперь arrayEnum содержит только два элемента без nil one.

...