简体   繁体   English

JSON 解码 Swift 中的双嵌套数组

[英]JSON decoding double nested array in Swift

currently I'm trying to decode JSON with a nested Array.目前我正在尝试使用嵌套数组解码 JSON。 The nested array can have some random numbers of the object inside it.嵌套数组可以在其中包含 object 的一些随机数。 I try to decode it but turns out it return an errors我尝试对其进行解码,但结果返回错误

CodingKeys(stringValue: "itenaries", intValue: nil),
debugDescription : "Expected to decode Array<Any> but found a dictionary 

Sample JSON data样本 JSON 数据

{
   "itenaries": {
      "days":
      [
         [
            {
               "itenary_id":0,
               "itenary_location_name":"Batu Caves Temple"
            }
     
         ],
         [
            {
               "itenary_id":0,
               "itenary_location_name":"KL Tower "
            },
            {
               "itenary_id":1,
               "itenary_location_name":"KL Forest Eco Park"
            }
         ]
      ]
   }
}

My Struct我的结构

struct Itenaries : Codable {
    let itenaries : [[Days]]
}

struct Days : Codable {
    let itenary_id : Int
    let itenary_location_name : String
}

Decoding Implementation解码实现

let decoder = JSONDecoder()
let itenary = try decoder.decode(Itenaries.self, from: fileData)
print(itenary.itenaries[0][0].itenary_id)

Where do you decode the days key?你在哪里解码days键? That's the problem.那就是问题所在。 You need an intermediate struct你需要一个中间结构

struct Root : Decodable {
    let itenaries : Itenary
}

struct Itenary : Decodable {
    let days : [[Days]]
}

... ...

let result = try decoder.decode(Root.self, from: fileData)
print(result.iternaries.days[0][0].itenary_id)

i'd probably do something like我可能会做类似的事情

struct Name:Codable {
    var itenaries:itenaries
}

struct itenaries:Codable {
    var days = [[Days]]
}
struct Days : Codable {
    let itenary_id : Int
    let itenary_location_name : String
}

so basically according the structure of your Json file Root struct -> itenaries -> [[days]]所以基本上根据你的 Json 文件的结构 Root struct -> itenaries -> [[days]]

hope you understand:)希望你能理解:)

[Edited] you can try these. [编辑]你可以试试这些。 I'm getting correct result using this approach我使用这种方法得到了正确的结果

Result结果

struct MainResponse : Codable {
    let itenaries : Itenaries
}

struct Itenaries : Codable {
    let days : [[Days]]
}

struct Days : Codable {
    let itenary_id : Int
    let itenary_location_name : String
}

if let path = Bundle.main.path(forResource: "nested_array", ofType: "json") {
    do {
        let responseData = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
        let decoder = JSONDecoder()
        let mainResponse = try decoder.decode(MainResponse.self, from: responseData)
        print(mainResponse.itenaries.days[0][0].itenary_id)
        print(mainResponse.itenaries.days[0][0].itenary_location_name)
        print(mainResponse.itenaries.days[1][0].itenary_id)
        print(mainResponse.itenaries.days[1][0].itenary_location_name)
        print(mainResponse.itenaries.days[1][1].itenary_id)
        print(mainResponse.itenaries.days[1][1].itenary_location_name)

        // output
        // 0
        // Batu Caves Temple
        // 0
        // KL Tower 
        // 1
        // KL Forest Eco Park
    } catch let error {
        print(error.localizedDescription)
    }
}

Your model is not correct, replace it by the following:您的 model 不正确,请将其替换为以下内容:

struct ItenariesResponse: Codable {
    let itenaries: Itenaries
}

struct Itenaries: Codable {
    let days: [[Day]]
}

struct Day: Codable {
    let itenaryID: Int
    let itenaryLocationName: String

    enum CodingKeys: String, CodingKey {
        case itenaryID = "itenary_id"
        case itenaryLocationName = "itenary_location_name"
    }
}

Then replace the type you decode like that:然后像这样替换您解码的类型:

let itenary = try decoder.decode(ItenariesResponse.self, from: fileData)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM