【问题标题】:How to decode JSON nested dictionary array with extension:decodable?如何解码带有扩展名的 JSON 嵌套字典数组:可解码?
【发布时间】:2021-03-22 11:30:35
【问题描述】:

我有这样的 JSON:

{
  "states" : [
    "C",
    "A",
    "B",
    "Sink",
  ],
  "symbols" : [
    "c",
    "a",
    "b"
  ],
  "transitions" : [
    {
      "with" : "c",
      "to" : "B",
      "from" : "C"
    },
    {
      "with" : "c",
      "to" : "Sink",
      "from" : "C"
    },
    {
      "with" : "b",
      "to" : "B",
      "from" : "B"
    },
    {
      "with" : "b",
      "to" : "Sink",
      "from" : "B"
    },
    {
      "with" : "c",
      "to" : "C",
      "from" : "A"
    },
    {
      "with" : "c",
      "to" : "Sink",
      "from" : "A"
    },
    {
      "with" : "a",
      "to" : "A",
      "from" : "A"
    },
    {
      "with" : "a",
      "to" : "Sink",
      "from" : "A"
    }
  ],
  "initialState" : "A",
  "finalStates" : [
    "B"
  ]
}

我无法解码 JSON 中的 transitions 部分(我需要像苹果在 here 中那样解码它)。 到目前为止我得到的是这个(注释部分是领先的错误 typeMismatch(Swift.Dictionary, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary,但找到了一个数组。”,基础错误:nil))

public struct FiniteAutomata {
    let states:[String]
    let symbols:[String]
    let initialState:String
    let finalStates:[String]
    /*
    let with:[String]
    let from:[String]
    let to:[String]
     */

    enum CodingKeys: String, CodingKey {
        case states
        case symbols
        case initialState
        case finalStates
        case transitions
    }
    /*
    enum transitionInfoKeys: String, CodingKey{
        case with
        case to
        case from
    }*/
}

extension FiniteAutomata: Decodable {
    public init(from decoder: Decoder)throws{
        let decoderContainer = try decoder.container(keyedBy: CodingKeys.self)
        states = try decoderContainer.decode([String].self, forKey: .states)
        symbols = try decoderContainer.decode([String].self, forKey: .symbols)
        initialState = try decoderContainer.decode(String.self, forKey: .initialState)
        finalStates = try decoderContainer.decode([String].self, forKey: .finalStates)
        /*
        let nestedContainer = try decoderContainer.nestedContainer(keyedBy: transitionInfoKeys.self, forKey: .transitions)
        with = try nestedContainer.decode([String].self, forKey: .with)
        to = try nestedContainer.decode([String].self, forKey: .to)
        from = try nestedContainer.decode([String].self, forKey: .from)
         */
    }
}

【问题讨论】:

  • 不清楚你到底想要什么。为什么要展平过渡?为什么注意有 struct Transition: Codable { let with: String; let to: String; let from: String }FiniteAutomata: let transitions: [Transition]let with:[String] 不是一个好主意,因为您将失去与 fromto 的同步。

标签: json swift codable decodable


【解决方案1】:

你需要

struct Transition: Decodable {
    let with,to,from:String
}

然后

let transitions : [Transition]

同时删除

public init(from decoder: Decoder)throws{
    let decoderContainer = try decoder.container(keyedBy: CodingKeys.self)
    states = try decoderContainer.decode([String].self, forKey: .states)
    symbols = try decoderContainer.decode([String].self, forKey: .symbols)
    initialState = try decoderContainer.decode(String.self, forKey: .initialState)
    finalStates = try decoderContainer.decode([String].self, forKey: .finalStates)
    /*
    let nestedContainer = try decoderContainer.nestedContainer(keyedBy: transitionInfoKeys.self, forKey: .transitions)
    with = try nestedContainer.decode([String].self, forKey: .with)
    to = try nestedContainer.decode([String].self, forKey: .to)
    from = try nestedContainer.decode([String].self, forKey: .from)
     */
}

因为这会自动发生,无需手动编写

【讨论】:

    【解决方案2】:

    transition 的值是一个字典数组,它变成了一个结构体数组

    struct Transition : Decodable {
       let with, to, from : String
    }
    

    然后解码

    let transitions : [Transition]
    

    不需要所有CodingKeys 和自定义init 方法

    【讨论】:

    • 谢谢 我不知道init是自动执行的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 2021-05-03
    • 1970-01-01
    相关资源
    最近更新 更多