gpt4 book ai didi

json - 解析具有可解码问题的 JSON

转载 作者:行者123 更新时间:2023-11-28 07:34:58 24 4
gpt4 key购买 nike

我正在尝试解析工作日的 JSON 时间表数据,每个工作日都有不同的事件/时间表数组,这些事件/时间表会重复每个弱点。所以我有一个数据数组,其中包含从星期一到星期日的工作日对象,而工作日则包含事件/计划数组。

struct Scheduledata: Decodable {
let data: [WeekDay]
}

struct WeekDay: Decodable {
let monday, tuesday, wednesday, thursday, friday, saturday, sunday : [Schedule]?

}

struct Schedule: Decodable {

let id: Int?
let start: String?
let end: String?
let address: String?
let name: String?
let text: String?
let imageURL: String?
let location: CLLocationCoordinate2D?


enum CodingKeys: String, CodingKey {
case text, location, start, end, name, address, id
case imageURL = "image_url"
}

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decodeIfPresent(Int.self, forKey: .id)
text = try container.decodeIfPresent(String.self, forKey: .text)
imageURL = try container.decodeIfPresent(String.self, forKey: .imageURL)
location = try container.decodeIfPresent(CLLocationCoordinate2D.self, forKey: .location)
start = try container.decodeIfPresent(String.self, forKey: .start)
end = try container.decodeIfPresent(String.self, forKey: .end)
address = try container.decodeIfPresent(String.self, forKey: .address)
name = try container.decodeIfPresent(String.self, forKey: .name)
}
}



extension CLLocationCoordinate2D: Codable {

public init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
self.init()
longitude = try container.decode(Double.self)
latitude = try container.decode(Double.self)
}

public func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(longitude)
try container.encode(latitude)
}
}

这是我要解析的 json 对象

{
"data": [
{
"monday": []
},
{
"tuesday": [
{
"id": 1,
"day_id": 2,
"start": "16:30",
"end": "21:00",
"name": "Test Event",
"address": "6 mohamed galal street cairo, heliopolis",
"lat": "30.0866280",
"long": "31.3236130",
"image": "http:\/\/80.211.174.200\/img\/event\/1542547661.jpeg",
"title": "Test_Event",
"description": "This is just a test event to test the testable testi test test testit test............................. yes this is a test indeed",
"created_at": "2018-11-18 15:27:41",
"updated_at": "2018-11-18 15:27:41"
}
]
},
{
"wednesday": []
},
{
"thursday": []
},
{
"friday": []
},
{
"saturday": []
},
{
"sunday": []
}
]
}

我期待的是一本字典:

var schedule = ["monday":[schedule], "tuesday":[schedule], ...]

我得到的似乎是一系列字典。我在每个工作日对象中只有一天,而不是一周中的所有日子。

var schedule = [["monday":[schedule], "tuesday":[schedule], ...],["monday":[schedule], "tuesday":[schedule], . ..]]

那我该怎么做呢?我为每一天创建不同的结构而不是工作日结构?好像不合逻辑有些事情是不对的。我确信有一个更智能的解决方案来解析它。

最佳答案

你的代码有两个问题:

1:您将许多属性声明为可选。当你这样做时,你隐藏了错误。你希望它在测试期间成功或失败,这样你就知道在哪里调试,而不是用 Optionals 掩盖它。

struct WeekDay: Decodable {
let monday, tuesday, ... : [Schedule]?
}

struct Schedule: Decodable {
let id: Int?
let start: String?
let end: String?
let address: String?
...
}

2:您的 JSON 真的很难处理。如果您可以控制服务器端,请将其更改为:

{
"data": [
"monday": [],
"tuesday": [{...}, {...}, ...],
"wednesday": [],
"thursday": [],
"friday": [],
"saturday": [],
"sunday": [],
]
}

假设您无法更改 JSON,下面是解码错误 JSON 的方法:

import Foundation
import CoreLocation

struct WeeklySchedule: Decodable {
let monday, tuesday, wednesday, thursday, friday, saturday, sunday: [Schedule]

private enum CodingKeys: String, CodingKey {
case data
}

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)

// Get the content of the `data` key from JSON
var subContainer = try container.nestedUnkeyedContainer(forKey: .data)

// Since you declare `monday`, etc. as `let` properties, they cannot
// be assigned multiple time. And the compiler does not know how
// many times the variable will be assigned to a `while` loop. So we
// need to define some local variables to temporarily hold the values.
var monday, tuesday, wednesday, thursday, friday, saturday, sunday: [Schedule]!

while !subContainer.isAtEnd {
let dailySchedule = try subContainer.decode([String: [Schedule]].self)

// The `first` value of a dictionary is non-deterministic since
// dictionaries do not have an order. But if the dictionary
// contains more than one weekday, there's a problem with the
// JSON anyway.
guard let (weekday, schedule) = dailySchedule.first else { continue }

switch weekday {
case "monday": monday = schedule
case "tuesday": tuesday = schedule
case "wednesday": wednesday = schedule
case "thursday": thursday = schedule
case "friday": friday = schedule
case "saturday": saturday = schedule
case "sunday": sunday = schedule
default: break
}
}

self.monday = monday
self.tuesday = tuesday
self.wednesday = wednesday
self.thursday = thursday
self.friday = friday
self.saturday = saturday
self.sunday = sunday
}
}

struct Schedule: Decodable {
let id: Int
let start: String
let end: String
let address: String
let name: String
let text: String
let imageURL: URL
let location: CLLocationCoordinate2D

private enum CodingKeys: String, CodingKey {
case start, end, name, address, id
case imageURL = "image", text = "description"
case lat, long
}

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.id = try container.decode(Int.self, forKey: .id)
self.start = try container.decode(String.self, forKey: .start)
self.end = try container.decode(String.self, forKey: .end)
self.address = try container.decode(String.self, forKey: .address)
self.name = try container.decode(String.self, forKey: .name)
self.text = try container.decode(String.self, forKey: .text)
self.imageURL = try container.decode(URL.self, forKey: .imageURL)

let latStr = try container.decode(String.self, forKey: .lat)
let longStr = try container.decode(String.self, forKey: .long)
guard let lat = CLLocationDegrees(latStr), let long = CLLocationDegrees(longStr) else {
fatalError("lat / long is not a number")
}
self.location = CLLocationCoordinate2D(latitude: lat, longitude: long)
}
}

let weeklySchedule = try JSONDecoder().decode(WeeklySchedule.self, from: jsonData)

关于json - 解析具有可解码问题的 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53463724/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com