在 Swift 中递归更改字典中的某些键
Recursively change some keys in a Dictionary in Swift
我有字典
var dictionary: Any = ["det" : ["val" : "some","result" : ["key1" : "val1","key2" : "val2"],"key3" :["val1", "val2"]]]
下面还有一个映射函数
func getMappedKey(_ key: String) -> String? {
var mapping: Dictionary = [
"key1" : "key3",
"key2" : "key4",
"det" : "data"
]
return mapping[key]
}
现在我想使用上面的映射函数更改同一个字典中的一些键。所以在改变之后,字典应该看起来像
["data" : ["val" : "some","result" : ["key3" : "val1","key4" : "val2"],"key3" :["val1", "val2"]]]
为此我在下面写了一个函数
func translatePayload(_ payload: inout Any) {
if let _ = payload as? String {
return
} else if var payload = payload as? Dictionary<String, Any> {
for (key, value) in payload {
if let newKey = getMappedKey(key) {
if let _ = payload.removeValue(forKey: key) {
payload[newKey] = value
}
}
var nextPayload = value
translatePayload(&nextPayload)
}
} else if let payload = payload as? Array<Any> {
for value in payload {
var nextPayload = value
translatePayload(&nextPayload)
}
}
}
当我调用函数时
translatePayload(&dictionary)
print(dictionary)
它不会更改同一字典中的键。有人可以指出这段代码有什么问题吗?提前致谢
您的代码非常好,您只是更新了局部变量而不是参数变量,因为您使用了相同的名称。只需将局部变量 payload
更改为 dictionary
和 array
或您喜欢的任何其他内容。
这是最终代码:
func translatePayload(_ payload: inout Any) {
if let _ = payload as? String {
return
} else if var dictionary = payload as? Dictionary<String, Any> { // Here dictionary instead of payload
for (key, value) in dictionary {
var nextPayload = value
translatePayload(&nextPayload)
if let newKey = getMappedKey(key) {
if let _ = dictionary.removeValue(forKey: key) {
dictionary[newKey] = nextPayload
}
} else {
dictionary[key] = nextPayload
}
}
payload = dictionary
} else if let array = payload as? Array<Any> { // Here array instead of payload
var updatedArray = array
for (index, value) in array.enumerated() {
var nextPayload = value
translatePayload(&nextPayload)
updatedArray[index] = nextPayload
}
payload = updatedArray // Assign the new changes
}
}
translatePayload(&dictionary)
print(dictionary)
并不是对问题 "what's wrong" 的直接回答,但我会选择类似的内容:
let dictionary = ["det" : ["val" : "some","result" : ["key1" : "val1", "key2" : "val2"],"key3" :["val1", "val2"]]]
func getMapped(key: String) -> String {
var mapping: Dictionary = [
"key1" : "key3",
"key2" : "key4",
"det" : "data"
]
return mapping[key] ?? key
}
func translate(payload:Any, map:(String)->String) -> Any {
switch payload {
case let value as String:
return value
case let value as [String:Any]:
return value.reduce(into:[String:Any]()) {
[=10=][map(.0)] = translate(payload: .1, map:map)
}
case let value as [Any]:
return value.map { translate(payload: [=10=], map:map) }
default:
fatalError("Unknown data type")
}
}
let output = translate(payload: dictionary, map:getMapped(key:))
真正利用 Swift 的功能精神。
我有字典
var dictionary: Any = ["det" : ["val" : "some","result" : ["key1" : "val1","key2" : "val2"],"key3" :["val1", "val2"]]]
下面还有一个映射函数
func getMappedKey(_ key: String) -> String? {
var mapping: Dictionary = [
"key1" : "key3",
"key2" : "key4",
"det" : "data"
]
return mapping[key]
}
现在我想使用上面的映射函数更改同一个字典中的一些键。所以在改变之后,字典应该看起来像
["data" : ["val" : "some","result" : ["key3" : "val1","key4" : "val2"],"key3" :["val1", "val2"]]]
为此我在下面写了一个函数
func translatePayload(_ payload: inout Any) {
if let _ = payload as? String {
return
} else if var payload = payload as? Dictionary<String, Any> {
for (key, value) in payload {
if let newKey = getMappedKey(key) {
if let _ = payload.removeValue(forKey: key) {
payload[newKey] = value
}
}
var nextPayload = value
translatePayload(&nextPayload)
}
} else if let payload = payload as? Array<Any> {
for value in payload {
var nextPayload = value
translatePayload(&nextPayload)
}
}
}
当我调用函数时
translatePayload(&dictionary)
print(dictionary)
它不会更改同一字典中的键。有人可以指出这段代码有什么问题吗?提前致谢
您的代码非常好,您只是更新了局部变量而不是参数变量,因为您使用了相同的名称。只需将局部变量 payload
更改为 dictionary
和 array
或您喜欢的任何其他内容。
这是最终代码:
func translatePayload(_ payload: inout Any) {
if let _ = payload as? String {
return
} else if var dictionary = payload as? Dictionary<String, Any> { // Here dictionary instead of payload
for (key, value) in dictionary {
var nextPayload = value
translatePayload(&nextPayload)
if let newKey = getMappedKey(key) {
if let _ = dictionary.removeValue(forKey: key) {
dictionary[newKey] = nextPayload
}
} else {
dictionary[key] = nextPayload
}
}
payload = dictionary
} else if let array = payload as? Array<Any> { // Here array instead of payload
var updatedArray = array
for (index, value) in array.enumerated() {
var nextPayload = value
translatePayload(&nextPayload)
updatedArray[index] = nextPayload
}
payload = updatedArray // Assign the new changes
}
}
translatePayload(&dictionary)
print(dictionary)
并不是对问题 "what's wrong" 的直接回答,但我会选择类似的内容:
let dictionary = ["det" : ["val" : "some","result" : ["key1" : "val1", "key2" : "val2"],"key3" :["val1", "val2"]]]
func getMapped(key: String) -> String {
var mapping: Dictionary = [
"key1" : "key3",
"key2" : "key4",
"det" : "data"
]
return mapping[key] ?? key
}
func translate(payload:Any, map:(String)->String) -> Any {
switch payload {
case let value as String:
return value
case let value as [String:Any]:
return value.reduce(into:[String:Any]()) {
[=10=][map(.0)] = translate(payload: .1, map:map)
}
case let value as [Any]:
return value.map { translate(payload: [=10=], map:map) }
default:
fatalError("Unknown data type")
}
}
let output = translate(payload: dictionary, map:getMapped(key:))
真正利用 Swift 的功能精神。