如何将 class / 结构转换为键与 属性 名称不同的字典

How to convert a class / struct into dictionary with key different as that of property name

我有一个结构,我想将它转换成字典,属性作为键,值作为值,但键不应该是 属性 名称,而是不同的东西,即 shopping_list_idshopping_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": "", ......]

的结果

您可以使用正则表达式转换为蛇形大小写,并使用反射(镜像)转换为字典。

正则表达式相当简单,如果您有多个大写字母,那么正则表达式将无法很好地工作,因此如果需要,可以改进这部分。

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: "_[=10=]", 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": "ABC", "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