【发布时间】:2021-04-06 21:22:08
【问题描述】:
我有两个数组(County 和 City 都符合 Comparable):
let array1 = [
Country(code: "US", cities: [
City(name: "Dallas"),
City(name: "New York")
]),
Country(code: "UK", cities: [
City(name: "London"),
City(name: "Manchester")
])
]
let array2 = [
Country(code: "DE", cities: [
City(name: "Munich"),
City(name: "Leipzig")
]),
Country(code: "US", cities: [
City(name: "Seattle")
City(name: "New York")
]),
Country(code: "UK", cities: [
City(name: "London"),
City(name: "Birmingham"),
City(name: "Manchester")
])
]
到目前为止,我设法将仅比较国家代码的那些结合起来:
let mergedArray = array1 + array2.filter { country in
return !array1.contains { $0.code == country.code }
}
我如何解释里面那些重复的城市?基本上得到这个:
let mergedArray = [
Country(code: "DE", cities: [
City(name: "Munich"),
City(name: "Leipzig")
]),
Country(code: "US", cities: [
City(name: "Dallas"),
City(name: "Seattle")
City(name: "New York")
]),
Country(code: "UK", cities: [
City(name: "London"),
City(name: "Birmingham"),
City(name: "Manchester")
])
]
也尝试过(没有为英国添加那些额外的城市):
func combine<T>(_ arrays: Array<T>?...) -> Set<T> {
return arrays.compactMap{$0}.compactMap{Set($0)}.reduce(Set<T>()){$0.union($1)}
}
并尝试过,但完全没有运气(很多重复):
let mergedArray = array1 + array2.filter { country in
return !array1.contains { $0.code == country.code } ||
(!array1.contains(where: { $0.cities?.contains(where: country.cities!.contains) as! Bool }))
}
【问题讨论】:
-
我会将第一个数组加载到字典中,以国家/地区名称为键。迭代你的第二个数组。检查字典是否有国家的条目,如果没有,只需将国家添加到字典中。如果是这样,您需要合并城市。最后将字典转换回数组。要合并城市数组,您可以将每个数组转换为一个集合,然后将两个集合的并集转换回一个数组。
-
你想尝试尽可能少的线条吗?如果不是,您不能只使用
ForEach遍历array1,并且对于与array2中的代码匹配的所有国家/地区,只需将城市对象添加到array1中的Country对象中。在末尾附加所有“不匹配”的国家/地区代码 -
是的,@Paulw11 和 @Rikh 的好主意,但如果可能的话,我只想要最干净的解决方案。当然,我可以手动遍历数组并使用
for和if来完成,但这不会很有趣:)