0

I’ve got JSON like this:

{
  "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"
  ]
}

I’m unable to decode transitions part the JSON(I need to decode it way that apple does in here). What I’ve got so far is this(commented part is leading error typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary<String, Any> but found an array instead.", underlyingError: 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)
         */
    }
}
1
  • It's unclear what you want in the end. Why do you want to flatten transitions? Why note have struct Transition: Codable { let with: String; let to: String; let from: String } and in FiniteAutomata: let transitions: [Transition] ? let with:[String] is not a good idea, because you'll loose the synchronization with from and to. Commented Mar 22, 2021 at 11:36

2 Answers 2

1

You need

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

Then

let transitions : [Transition]

Also Remove

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)
     */
}

as this will occur automatically no need to write it manually

Sign up to request clarification or add additional context in comments.

Comments

1

The value for key transition is an array of dictionaries which becomes an array of a struct

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

Then decode

let transitions : [Transition]

All CodingKeys and the custom init method is not needed

1 Comment

Thanks I had no idea that init is being executed automatically

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.