Reputation: 1177
I have a struct and I want to convert that into Dictionary with properties as Key and their value as Value but the key should not be the property name but something different i.e. shopping_list_id
OR 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
}
I need to have a method for struct getDictionaryEquivalent()
which can result something like ["shopping_list_name":"", "shopping_list_id": "", ......]
Upvotes: 0
Views: 473
Reputation: 51993
You can use a regular expression to convert to snake case and use reflection (Mirror) to convert to a dictionary.
The regex is rather simple and will not work so well if you for instance have several uppercase letters after each other so this part could be improved if needed.
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
}
Example if usage
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))
prints
["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"]
But of course if the goal is to create json data it is quite simple
Make the struct conform to Codable
and then set the keyEncodingStrategy
property when encoding
let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
Upvotes: 1