arrays - 根据对象字段减少对象数组

标签 arrays swift

我有一个 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 })
}

由于 namecountryName 的值未知,因此我使用了空的 String ("" )对于两者。

关于arrays - 根据对象字段减少对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64046751/

相关文章:

ios - 将节点设置为从一系列点随机生成并以逐渐加快的速度下降

php - 如何将数组分配给sql查询的变量

ios - 如何调整 UIView 的 Y anchor ?

ios - 如何使用 Eureka 框架根据所选值隐藏行/部分

ios - 当我在 Swift 中打印一个数组时,它的类型(<__NSArrayM 0x60800024a1a0>)也随之而来。为什么?

mysql - 获取数据库中相似行的数量并在表单中单独显示它们

javascript - 如何按值过滤嵌套的对象数组并获取根对象

string - 在swift中用单个字符替换字符串中的空格序列

iOS App运行后台任务时间

arrays - Swift : How do i create an array of dictionaries, 其中每个字典都包含一个数组?