在 Swift4 中将具有值的字典合并为数组
Merge Dictionaries With Values As Arrays in Swift4
我有三个词典,我想合并它们。请帮忙!
词典 1:
"Abc": {
"Def": {
"Jkl": "xxx",
}
}
词典 2:
"Abc": {
"Ghi": {
"Mno": "yyy",
}
}
词典 3:
"Abc": {
"Ghi": {
"Pqr": "zzz"
}
}
我希望生成的字典将相似的值组合在一起,它应该如下所示:
"Abc": {
"Def: {
"Jkl": "xxx"
},
"Ghi": {
"Mno": "yyy",
"Pqr": "zzz"
}
}
使用这个递归方法连接两个字典
func deepMerge(a: [String: Any], b: [String: Any]) -> [String: Any] {
var result = a
for (key, value) in b {
//Key matches
if let aValue = result[key] {
//Both values are dictionaries
if let aValDict = aValue as? [String: Any], let bValDict = value as? [String: Any] {
result[key] = deepMerge(a: aValDict, b: bValDict)
} else {
//One/both values aren't dictionaries
print("Expected two dictionaries to merge")
}
} else {
//Different keys
return a.merging(b) { (_, new) in new }
}
}
return result
}
用法
let dict1 = ["Abc": ["Def": ["Jkl": "xxx"]]]
let dict2 = ["Abc": ["Ghi": ["Mno": "yyy"]]]
let dict3 = ["Abc": ["Ghi": ["Pqr": "zzz"]]]
var result = [String: Any]()
for dict in [dict1, dict2, dict3] {
result = deepMerge(a: result, b: dict)
}
print(result)
//["Abc": ["Ghi": ["Pqr": "zzz", "Mno": "yyy"], "Def": ["Jkl": "xxx"]]]
iOSDev 解决方案是很好的且不言自明的递归函数。
我会在这里添加另一种使用 Swift 方法 merging(_:uniquingKeysWith:)
来处理字典的方法
Creates a dictionary by merging key-value pairs in a sequence into the dictionary, using a combining closure to determine the value for duplicate keys.
可用
您的解决方案可能看起来很自然
func mergeStandard(_ one: [String: [String: [String: String]]],
_ two: [String: [String: [String: String]]]) -> [String: [String: [String: String]]] {
return one.merging(two) {
[=10=].merging() {
[=10=].merging() { value1, value2 -> String in
return value1 // which is logically wrong, as we should have both values, see the Further Steps section
}
}
}
}
let a = ["Abc": ["Def": ["Jkl": "xxx"]]]
let b = ["Abc": ["Ghi": ["Mno": "yyy"]]]
let c = ["Abc": ["Ghi": ["Pqr": "zzz"]]]
let d = mergeStandard(a, b)
let e = mergeStandard(d, c)
print(e)
//["Abc": ["Def": ["Jkl": "xxx"], "Ghi": ["Mno": "yyy", "Pqr": "zzz"]]]
N.B.!
当你尝试一些不同的输入时,比如
let a = ["Abc": ["Def": ["Jkl": "xxx"]]]
let b = ["Abc": ["Ghi": ["Mno": "yyy", "Pqr": "qqq"]]]
let c = ["Abc": ["Ghi": ["Pqr": "zzz"]]]
因为你有两个 "Pqr"
键。上面的代码将 select 键 "Pqr"
的值 "qqq"
。另一个答案 - 来自 iOSDev 有同样的问题。请在下面查看此案例的解决方案。
进一步的步骤
我建议您将数据结构更改为 [String: [String: [String: [String]]]]
,这样您的最后一个值将是 String
的 Sequence
。
然后你可以使用以下内容:
func mergeUpgraded(_ one: [String: [String: [String: [String]]]],
_ two: [String: [String: [String: [String]]]]) -> [String: [String: [String: [String]]]] {
return one.merging(two) {
[=12=].merging() {
[=12=].merging() { (arr1, arr2) -> [String] in
var a = arr1
var b = arr2
a.append(contentsOf: b)
return a
}
}
}
}
let a = ["Abc": ["Def": ["Jkl": ["xxx"]]]]
let b = ["Abc": ["Ghi": ["Mno": "yyy", "Pqr": "qqq"]]]
let c = ["Abc": ["Ghi": ["Pqr": "zzz"]]]
let d = mergeUpgraded(a, b)
let e = mergeUpgraded(d, c)
print(e)
// ["Abc": ["Ghi": ["Mno": ["yyy"], "Pqr": ["qqq", "zzz"]], "Def": ["Jkl": ["xxx"]]]]
谢谢大家的帮助!这段代码对我有用:
private func deepMerge(_ d1: [String: Any], _ d2: [String: Any]) -> [String: Any] {
var result = d1
for (k2, v2) in d2 {
if let v1 = result[k2] as? [String: Any], let v2 = v2 as? [String: Any] {
result[k2] = deepMerge(v1, v2)
} else {
result[k2] = v2
}
}
return result
}
我有三个词典,我想合并它们。请帮忙!
词典 1:
"Abc": {
"Def": {
"Jkl": "xxx",
}
}
词典 2:
"Abc": {
"Ghi": {
"Mno": "yyy",
}
}
词典 3:
"Abc": {
"Ghi": {
"Pqr": "zzz"
}
}
我希望生成的字典将相似的值组合在一起,它应该如下所示:
"Abc": {
"Def: {
"Jkl": "xxx"
},
"Ghi": {
"Mno": "yyy",
"Pqr": "zzz"
}
}
使用这个递归方法连接两个字典
func deepMerge(a: [String: Any], b: [String: Any]) -> [String: Any] {
var result = a
for (key, value) in b {
//Key matches
if let aValue = result[key] {
//Both values are dictionaries
if let aValDict = aValue as? [String: Any], let bValDict = value as? [String: Any] {
result[key] = deepMerge(a: aValDict, b: bValDict)
} else {
//One/both values aren't dictionaries
print("Expected two dictionaries to merge")
}
} else {
//Different keys
return a.merging(b) { (_, new) in new }
}
}
return result
}
用法
let dict1 = ["Abc": ["Def": ["Jkl": "xxx"]]]
let dict2 = ["Abc": ["Ghi": ["Mno": "yyy"]]]
let dict3 = ["Abc": ["Ghi": ["Pqr": "zzz"]]]
var result = [String: Any]()
for dict in [dict1, dict2, dict3] {
result = deepMerge(a: result, b: dict)
}
print(result)
//["Abc": ["Ghi": ["Pqr": "zzz", "Mno": "yyy"], "Def": ["Jkl": "xxx"]]]
iOSDev 解决方案是很好的且不言自明的递归函数。 我会在这里添加另一种使用 Swift 方法 merging(_:uniquingKeysWith:)
来处理字典的方法可用Creates a dictionary by merging key-value pairs in a sequence into the dictionary, using a combining closure to determine the value for duplicate keys.
您的解决方案可能看起来很自然
func mergeStandard(_ one: [String: [String: [String: String]]],
_ two: [String: [String: [String: String]]]) -> [String: [String: [String: String]]] {
return one.merging(two) {
[=10=].merging() {
[=10=].merging() { value1, value2 -> String in
return value1 // which is logically wrong, as we should have both values, see the Further Steps section
}
}
}
}
let a = ["Abc": ["Def": ["Jkl": "xxx"]]]
let b = ["Abc": ["Ghi": ["Mno": "yyy"]]]
let c = ["Abc": ["Ghi": ["Pqr": "zzz"]]]
let d = mergeStandard(a, b)
let e = mergeStandard(d, c)
print(e)
//["Abc": ["Def": ["Jkl": "xxx"], "Ghi": ["Mno": "yyy", "Pqr": "zzz"]]]
N.B.! 当你尝试一些不同的输入时,比如
let a = ["Abc": ["Def": ["Jkl": "xxx"]]]
let b = ["Abc": ["Ghi": ["Mno": "yyy", "Pqr": "qqq"]]]
let c = ["Abc": ["Ghi": ["Pqr": "zzz"]]]
因为你有两个 "Pqr"
键。上面的代码将 select 键 "Pqr"
的值 "qqq"
。另一个答案 - 来自 iOSDev 有同样的问题。请在下面查看此案例的解决方案。
进一步的步骤
我建议您将数据结构更改为 [String: [String: [String: [String]]]]
,这样您的最后一个值将是 String
的 Sequence
。
然后你可以使用以下内容:
func mergeUpgraded(_ one: [String: [String: [String: [String]]]],
_ two: [String: [String: [String: [String]]]]) -> [String: [String: [String: [String]]]] {
return one.merging(two) {
[=12=].merging() {
[=12=].merging() { (arr1, arr2) -> [String] in
var a = arr1
var b = arr2
a.append(contentsOf: b)
return a
}
}
}
}
let a = ["Abc": ["Def": ["Jkl": ["xxx"]]]]
let b = ["Abc": ["Ghi": ["Mno": "yyy", "Pqr": "qqq"]]]
let c = ["Abc": ["Ghi": ["Pqr": "zzz"]]]
let d = mergeUpgraded(a, b)
let e = mergeUpgraded(d, c)
print(e)
// ["Abc": ["Ghi": ["Mno": ["yyy"], "Pqr": ["qqq", "zzz"]], "Def": ["Jkl": ["xxx"]]]]
谢谢大家的帮助!这段代码对我有用:
private func deepMerge(_ d1: [String: Any], _ d2: [String: Any]) -> [String: Any] {
var result = d1
for (k2, v2) in d2 {
if let v1 = result[k2] as? [String: Any], let v2 = v2 as? [String: Any] {
result[k2] = deepMerge(v1, v2)
} else {
result[k2] = v2
}
}
return result
}