带有不同数组类型的Swift Codable [英] Swift Codable with Different Array Types

查看:161
本文介绍了带有不同数组类型的Swift Codable的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个程序,在其中解析 JSON 数据,其中包括数组数组,其中嵌套的数组具有不同的对象类型(特别是[[String, String,Int]])。例如,

I'm writing a program where I'm parsing JSON data that includes array of arrays, where the nested arrays have different object types (specifically, [[String, String, Int]]). For example,

{
"number": 5295,
"bets": [
    [
        "16",
        "83",
        9
    ],
    [
        "75",
        "99",
        4
    ],
    [
        "46",
        "27",
        5
    ]
]
}

我正在尝试使用可编码来帮助我解析数据,但是当我尝试某些操作时例如

I'm trying to use codable to help me parse the data, but when I try something like

struct OrderBook: Codable {
    let number: Int
    let bets: [Bet]
}

struct Bet: Codable {
    let price: String
    let sale: String
    let quantity: Int
}

它给了我一个错误,即


预期对Dictionary < String,Any> 进行解码,但找到一个数组代替

Expected to decode Dictionary<String, Any> but found an array instead

我该如何解决?我无法声明一个空类型的数组。

How do I get around this? I can't declare an array of empty type.

推荐答案

一种解决方案(假设您无法更改JSON)是为实现自定义解码逻辑下注。为了依次解码每个属性(调用 decode(_:)的顺序),可以使用一个无密钥的容器(从JSON数组中读取)。

One solution (assuming you can't change the JSON) is to implement custom decoding logic for Bet. You can use an unkeyed container (which reads from a JSON array) in order to decode each of the properties in turn (the order in which you call decode(_:) is the order they're expected to appear in the array).

import Foundation

struct OrderBook : Codable {
  let number: Int
  let bets: [Bet]
}

struct Bet : Codable {
  let price: String
  let sale: String
  let quantity: Int

  init(from decoder: Decoder) throws {
    var container = try decoder.unkeyedContainer()
    self.price = try container.decode(String.self)
    self.sale = try container.decode(String.self)
    self.quantity = try container.decode(Int.self)
  } 

  // if you need encoding (if not, make Bet Decodable
  // and remove this method)
  func encode(to encoder: Encoder) throws {
    var container = encoder.unkeyedContainer()
    try container.encode(price)
    try container.encode(sale)
    try container.encode(quantity)
  }
}

示例解码:

let jsonString = """
{ "number": 5295, "bets": [["16","83",9], ["75","99",4], ["46","27",5]] }
"""

let jsonData = Data(jsonString.utf8)

do {
  let decoded = try JSONDecoder().decode(OrderBook.self, from: jsonData)
  print(decoded)
} catch {
  print(error)
}

// OrderBook(number: 5295, bets: [
//   Bet(price: "16", sale: "83", quantity: 9),
//   Bet(price: "75", sale: "99", quantity: 4),
//   Bet(price: "46", sale: "27", quantity: 5)
// ])

这篇关于带有不同数组类型的Swift Codable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆