我有一个 Country
对象和一个 City
对象
struct Country: {
let name: String
let countryCode: String
let cities: [City]
let population: Int
init(name: String, countryCode: String, cities: [City], population: Int) {
self.name = name
self.countryCode = countryCode
self.cities = cities
self.population = population
}
}
struct City {
let id: Int
let name: String
let latitude: Double
let longitude: Double
let countryCode: String
let population: Int
}
传入的 JSON
数据如下所示,解码为 [City]
数组
{
"cities":[
{
"id":1,
"name":"Paris",
"latitude":0,
"logitude":0,
"country_code":"FR",
"population":0
},
{
"id":2,
"name":"Nice",
"latitude":0,
"logitude":0,
"country_code":"FR",
"population":0
},
{
"id":3,
"name":"Berlin",
"latitude":0,
"logitude":0,
"country_code":"DE",
"population":0
},
{
"id":4,
"name":"Munich",
"latitude":0,
"logitude":0,
"country_code":"DE",
"population":0
},
{
"id":5,
"name":"Amsterdam",
"latitude":0,
"logitude":0,
"country_code":"NL",
"population":0
},
{
"id":6,
"name":"Leiden",
"latitude":0,
"logitude":0,
"country_code":"NL",
"population":0
}
]
}
如何有效地从 [City]
数组创建 [Country]
数组?我尝试过使用 reduce:into:
但不确定这就是我必须使用的。
我知道我可以使用一个空数组并一一添加/创建国家/地区,然后搜索是否已有国家/地区并将城市添加到其中。对我来说这会创建看起来很糟糕的代码。我觉得使用map或reduce函数有一个优雅的解决方案来解决这个问题。
reduce:into:
到目前为止我尝试过的代码
func transformArrayOf(_ cities: [City]) -> [Country] {
let empty: [Country] = []
return cities.reduce(into: empty) { countries, city in
let existing = countries.filter { $0.countryCode == city.countryCode }.first
countries[existing].cities.append(city)
}
}
编辑:
该函数仅获取[City]
数组。因此,国家只能由此创建。
Dictionary(grouping:by:)
与 map(_:)
完美配合!嵌套 for
循环和 if
语句上有两行:)
并且国家
名称可以从国家/地区代码解析
最佳答案
结合使用Dictionary(grouping:by:)
和map(_:)
来得到预期的结果结果。
let countries = Dictionary(grouping: cities, by: { $0.countryCode }).map { (countryCode, cities) -> Country in
return Country(name: "", countryCode: countryCode, countryName: "", cities: cities, population: cities.reduce(0) { $0 + $1.population })
}
由于 name
和 countryName
的值未知,因此我使用了空的 String
(""
)对于两者。
关于arrays - 根据对象字段减少对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64046751/