首页 > 解决方案 > 将对象数组与里面的子对象数组合并

问题描述

我有两个数组(两者CountyCity符合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 }))
}

标签: iosarraysswift

解决方案


你能做出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))
}

推荐阅读