【问题标题】:Grab value of a dictionary that is in an array获取数组中字典的值
【发布时间】:2019-04-13 23:03:35
【问题描述】:

我正在尝试从数组中的字典中获取一些值,但我不知道该怎么做。我能够从字典和数组中抓取东西,但不能将它们结合起来。如果有帮助的话,我正在使用 openweathermap 每小时 api。

我尝试将我所做的两种不同方式结合起来,但没有奏效。这是我尝试过的:

struct HourlyWeatherAPI: Decoder
{
    let main: Main
    let wind: Wind
    struct Main: Decodable
    {
        let temp: Double
    }
    struct Wind: Decodable
    {
        let speed, deg: Double
    }
}

-^ 在我的代码的顶部,然后这要晚得多

if let tempJson = jsonObject["list"] as? [[String:AnyObject]]
{
    for eachTemp in tempJson
    {
        let decoder = JSONDecoder()
        decoder.keyDecodingStrategy = .convertFromSnakeCase
        let result = try decoder.decode(HourlyWeatherAPI.Main.self, from: data!)
        print(result.temp)
    }
}

这是 API 中的一些内容,只是第一个条目。我正在尝试获取 main 中的内容:

{
    "cod": "200",
    "message": 0.0197,
    "cnt": 96,
    "list": [
        {
            "dt": 1555196400,
            "main": {
                "temp": 282.26,
                "temp_min": 281.409,
                "temp_max": 282.26,
                "pressure": 1018.06,
                "sea_level": 1018.06,
                "grnd_level": 985.672,
                "humidity": 56,
                "temp_kf": 0.85
            },
            "weather": [
                {
                    "id": 804,
                    "main": "Clouds",
                    "description": "overcast clouds",
                    "icon": "04d"
                }
            ],
            "clouds": {
                "all": 100
            },
            "wind": {
                "speed": 3.99,
                "deg": 313.922
            },
            "sys": {
                "pod": "d"
            },
            "dt_txt": "2019-04-13 23:00:00"
        },

【问题讨论】:

  • 您应该创建一个结构来表示具有至少list 属性的根级别对象。然后您可以将JSON 解码为该类型并访问列表
  • 无关:我认为你应该调整HourlyWeatherAPI。一方面,它不是 API,而是数据传输对象 (DTO)。每小时一次也没关系。如果有另一个天气 API 提供每日天气摘要,那么模型对象将几乎相同。请考虑:WeatherSnapshot,或者类似的东西。
  • @DennisW。那么我会像我已经拥有的那样制作另一个还是改变我拥有的那个?
  • 我认为您需要另一个,您将 list 中的项目作为 HourlyWeatherAPI 结构,但您需要一个包含 list 的结构。类似struct Root:Codable { let list: [HourlyWeatherAPI] }
  • @DennisW。我添加了它,但是当我按照您所说的方式放置时,它“不符合协议'Encodable'”

标签: ios swift openweathermap


【解决方案1】:

您希望数据结构与您收到的 JSON 相匹配,从根级别对象开始。然后您可以解码根对象并访问包含的数据结构。

struct Root: Decodable {
     let list:[HourlyWeatherAPI]
}

struct HourlyWeatherAPI: Decodable {
     let main: Main
     let wind: Wind
}

struct Main: Decodable {
    let temp: Double
}

struct Wind: Decodable {
    let speed, deg: Double
}

/* 
 * decode your JSON as before, but use the new Root object as the type. You
 * can then access the hourly weather data from the list property
 */
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let result = try decoder.decode(Root.self, from: data!)
let hourlyWeatherList = result.list
let firstWeatherItem = hourlyWeatherList[0]
let temp = firstWeatherItem.main.temp

【讨论】:

  • 那我该怎么称呼它呢?喜欢打印出来
  • root 对象将包含您可以访问的 listHourlyWeatherAPI 对象。
  • 会不会是这样的:let result = try decoder.decode(Root.init(list: Main), from: data!)
  • 我在答案底部添加了如何访问list。你不需要init 任何东西,Root 对象将包含天气项目的list 作为属性。 Decodable 协议将负责为您制作所有嵌套数据结构。
  • 好的,现在我在你编辑后打印出来了。我将如何抓住温度或风速?因为现在它正在打印出来
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多