将对象数组与里面的子对象数组合并
Posted
技术标签:
【中文标题】将对象数组与里面的子对象数组合并【英文标题】:Merge object arrays with child object arrays inside 【发布时间】: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.compactMapSet($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
来完成,但这不会很有趣:)
【参考方案1】:
你能让City
符合Hashable
吗?如果是这样,试试这个:
var dict = [String: Set<City>]() // code -> cities
for country in array1 + array2
dict[country.code, default: Set<City>()].formUnion(country.cities)
// convert back to array
let mergedArray = dict.map code, cities in
Country(code: code, cities: Array(cities))
【讨论】:
啊!那是天才 :) 所以基本上Set
中的项目不能有重复项,因此可以完美运行。基本上4行代码!谢谢!以上是关于将对象数组与里面的子对象数组合并的主要内容,如果未能解决你的问题,请参考以下文章