Как преобразовать класс / структуру в словарь с ключом, отличным от имени свойства - PullRequest
0 голосов
/ 29 апреля 2020

У меня есть структура, и я хочу преобразовать ее в словарь со свойствами в качестве ключа и их значением в качестве значения, но ключ должен быть не именем свойства, а чем-то другим, т.е. shopping_list_id ИЛИ shopping_list_name.

struct AddItemToEvent {
  var key: String
  var shoppingListId: String   //shopping_list_id
  var shoppingListName: String   //shopping_list_name
  var commonName: String
  var storeCode: String
  var sourceType: String
  var sourceId: String
  var isDefaultList: String
  var storeLocation: String

//  shopping_list_id, shopping_list_name, common_name, store_code, source_type (offer, promotion, normal, favourite), source_id, default_list, store_location, client_id 
}

Мне нужен метод для структуры getDictionaryEquivalent(), который может привести к чему-то вроде ["shopping_list_name":"", "shopping_list_id": "", ......]

1 Ответ

1 голос
/ 29 апреля 2020

Вы можете использовать регулярное выражение для преобразования в регистр змеи и использовать отражение (Mirror) для преобразования в словарь.

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

func snakeKeyDictionary(_ mirror: Mirror) -> [String: Any] {
    var dictionary = [String: Any]()
    for (key, value) in mirror.children {
        if let key = key {
            let snakeKey = key.replacingOccurrences(of: #"[A-Z]"#, with: "_$0", options: .regularExpression).lowercased()
            dictionary[snakeKey] = value
        }
    }
    return dictionary
}

Пример использования

let item = AddItemToEvent(key: "1", shoppingListId: "12", shoppingListName: "List", 
    commonName: "some", storeCode: "ABC", sourceType: "A", sourceId: "fgd", 
    isDefaultList: "yes", storeLocation: "home")

let mirror = Mirror(reflecting: item)
print(snakeKeyDictionary(mirror))

печать

["common_name": " some "," is_default_list ":" yes "," store_code ":" AB C "," store_location ":" home "," key ":" 1 "," shopping_list_name ":" List "," source_id ": "fgd", "shopping_list_id": "12", "source_type": "A"]

Но, конечно, если целью является создание json данных, это довольно просто

Привести структуру в соответствие Codable, а затем установить свойство keyEncodingStrategy при кодировании

let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
...