Swiftwater Logo

Writing A Robust Little Parser in Swift –Part 2

This entry is part 13 of 17 in the series Swiftwater

ABSTRACT

In the previous post, we talked about the need to write a “middleman” parser engine that takes a varied dataset, and condenses it all into a single, well-specified Swift format.

In this post, we’ll examine the task and the specs, and hammer out a basic requirement.

SCOPING THE PROBLEM DOMAIN

The first thing that we do, is review the various structures that our data could take, upon presentation to our parser. If you recall, in Part 1, we mapped out a huge range of possibilities, spelled out in JSON (NOTE: Removed 4 of each set of values to reduce the complexity of this display –it needs all the help it can get):

{"containerElement": {"arrayElement": ["Element Value 01"]}}

{"containerElement": [
                        {"arrayElement": "Element Value 01"}
                    ]
}


{"containerElement": [
                        {"arrayElement": {"value": "Element Value 01"}}
                    ]
}

{"containerElement": {"arrayElement": [
                                        {"value": "Element Value 01"}
                                    ]
                    }
}

{"containerElement": {"arrayElement": ["Element Value 01"]}}

{"containerElement": [
                        {"arrayElement": {"attributes": [
                                                            {"value": "Element Value 01"}
                                                        ]
                                        }
                        }
                    ]
}

{"containerElement": [
                        {"arrayElement": {"attributes": {"value": "Element Value 01"}}}
                    ]
}


{"containerElement": [
                        {"arrayElement": [
                                            {"attributes": [
                                                                {"index": 0}
                                                            ]
                                            },
                                            {"value": "Element Value 01"}
                                        ]
                        }
                    ]
}

{"containerElement": [
                        {"arrayElement": [
                                            {"attributes": [
                                                                {"index": "0"}
                                                            ]
                                            },
                                            {"value": "Element Value 01"}
                                        ]
                        }
                    ]
}

{"containerElement": [
                        {"arrayElement": [
                                            {"attributes": {"index": "0"}},
                                            {"value": "Element Value 01"}
                                        ]
                        }
                    ]
}

{"containerElement": [
                        {"arrayElement": [
                                            {"attributes": [
                                                                {"index": "0"},
                                                                {"value": "Element Value 01"}
                                                            ]
                                            }
                                        ]
                        }
                    ]
}

{"containerElement": [
                        {"arrayElement": {"attributes": [
                                                            {"row": 0},
                                                            {"value": "Element Value 01"}
                                                        ]
                                        }
                        }
                    ]
}

{"containerElement": [
                        {"arrayElement": [
                                            {"attributes": [
                                                                {"row": 0},
                                                                {"value": "Element Value 01"}
                                                            ]
                                            }
                                        ]
                        }
                    ]
}

{"containerElement": [
                        {"arrayElement": {"attributes": [
                                                            {"row": "0"},
                                                            {"value": "Element Value 01"}
                                                        ]
                                        }
                        }
                    ]
}

{"containerElement": [
                        {"arrayElement": [
                                            {"attributes": [
                                                                {"row": "0"},
                                                                {"value": "Element Value 01"}
                                                            ]
                                            }
                                        ]
                        }
                    ]
}

Pretty crazy, huh? And we want to boil it down to this:

["Element Value 01"]

That means that we need to hunt down that “Element Value 01”, wherever it lives in the data. It could be a top-level raw value, or buried several layers down, inside an attributes array.

Our parser needs to be able to ingest ALL of that, burp demurely, and emit a single, simple Swift Array of String, with each value as an Array element.

The Function Signature

Before we proceed, let’s establish our function signature, based on what we know:

func myParser(_ inDictionaryToBeParsed: [String: Any]) -> [String]

We should also be thinking about testing. This is pretty much exactly the kind of thing we should be testing as thoroughly as possible, as these things get buried deep inside infrastructures, where they are forgotten until they raise their ugly heads and savage the quality of the finished product.

Why don’t we set up an Array of pre-built Dictionary<String, Any> instances, containing expressions of the above scenarios?

The Test Set

func convertJSONToDictionary(_ inJSON: String) -> [String: Any] {
    do {
        if let stringData = inJSON.data(using: .utf8), let jsonDict = try JSONSerialization.jsonObject(with: stringData) as? [String: Any] {
            return jsonDict
        }
    } catch(let error) {
        print(String(describing: error))
    }
    return [:]
}

var jsonInterpretations: [[String: Any]] = []

func loadJSONIntoDictionaries() {
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": \"Element Value 01\"}, {\"arrayElement\": \"Element Value 02\"}, {\"arrayElement\": \"Element Value 03\"}, {\"arrayElement\": \"Element Value 04\"}, {\"arrayElement\": \"Element Value 05\"}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": {\"arrayElement\": [\"Element Value 01\", \"Element Value 02\", \"Element Value 03\", \"Element Value 04\", \"Element Value 05\"]}}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": {\"value\": \"Element Value 01\"}}, {\"arrayElement\": {\"value\": \"Element Value 02\"}}, {\"arrayElement\": {\"value\": \"Element Value 03\"}}, {\"arrayElement\": {\"value\": \"Element Value 04\"}}, {\"arrayElement\": {\"value\": \"Element Value 05\"}}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": {\"arrayElement\": [{\"value\": \"Element Value 01\"}, {\"value\": \"Element Value 02\"}, {\"value\": \"Element Value 03\"}, {\"value\": \"Element Value 04\"}, {\"value\": \"Element Value 05\"}]}}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": {\"arrayElement\": [\"Element Value 01\", \"Element Value 02\", \"Element Value 03\", \"Element Value 04\", \"Element Value 05\"]}}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": {\"attributes\": [{\"value\": \"Element Value 01\"}]}}, {\"arrayElement\": {\"attributes\": [{\"value\": \"Element Value 02\"}]}}, {\"arrayElement\": {\"attributes\": [{\"value\": \"Element Value 03\"}]}}, {\"arrayElement\": {\"attributes\": [{\"value\": \"Element Value 04\"}]}}, {\"arrayElement\": {\"attributes\": [{\"value\": \"Element Value 05\"}]}}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": {\"attributes\": {\"value\": \"Element Value 01\"}}}, {\"arrayElement\": {\"attributes\": {\"value\": \"Element Value 02\"}}}, {\"arrayElement\": {\"attributes\": {\"value\": \"Element Value 03\"}}}, {\"arrayElement\": {\"attributes\": {\"value\": \"Element Value 04\"}}}, {\"arrayElement\": {\"attributes\": {\"value\": \"Element Value 05\"}}}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": [{\"attributes\": [{\"index\": 0}]}, {\"value\": \"Element Value 01\"}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": 1}]}, {\"value\": \"Element Value 02\"}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": 2}]}, {\"value\": \"Element Value 03\"}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": 3}]}, {\"value\": \"Element Value 04\"}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": 4}]}, {\"value\": \"Element Value 05\"}]}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": [{\"attributes\": [{\"index\": \"0\"}]}, {\"value\": \"Element Value 01\"}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": \"1\"}]}, {\"value\": \"Element Value 02\"}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": \"2\"}]}, {\"value\": \"Element Value 03\"}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": \"3\"}]}, {\"value\": \"Element Value 04\"}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": \"4\"}]}, {\"value\": \"Element Value 05\"}]}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": [{\"attributes\": {\"index\": \"0\"}}, {\"value\": \"Element Value 01\"}]}, {\"arrayElement\": [{\"attributes\": {\"index\": \"1\"}}, {\"value\": \"Element Value 02\"}]}, {\"arrayElement\": [{\"attributes\": {\"index\": \"2\"}}, {\"value\": \"Element Value 03\"}]}, {\"arrayElement\": [{\"attributes\": {\"index\": \"3\"}}, {\"value\": \"Element Value 04\"}]}, {\"arrayElement\": [{\"attributes\": {\"index\": \"4\"}}, {\"value\": \"Element Value 05\"}]}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": [{\"attributes\": [{\"index\": \"0\"}, {\"value\": \"Element Value 01\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": \"1\"}, {\"value\": \"Element Value 02\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": \"2\"}, {\"value\": \"Element Value 03\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": \"3\"}, {\"value\": \"Element Value 04\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": \"4\"}, {\"value\": \"Element Value 05\"}]}]}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": {\"attributes\": [{\"row\": 0}, {\"value\": \"Element Value 01\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": 1}, {\"value\": \"Element Value 02\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": 2}, {\"value\": \"Element Value 03\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": 3}, {\"value\": \"Element Value 04\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": 4}, {\"value\": \"Element Value 05\"}]}}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": [{\"attributes\": [{\"row\": 0}, {\"value\": \"Element Value 01\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"row\": 1}, {\"value\": \"Element Value 02\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"row\": 2}, {\"value\": \"Element Value 03\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"row\": 3}, {\"value\": \"Element Value 04\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"row\": 4}, {\"value\": \"Element Value 05\"}]}]}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": {\"attributes\": [{\"row\": \"0\"}, {\"value\": \"Element Value 01\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": \"1\"}, {\"value\": \"Element Value 02\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": \"2\"}, {\"value\": \"Element Value 03\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": \"3\"}, {\"value\": \"Element Value 04\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": \"4\"}, {\"value\": \"Element Value 05\"}]}}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": [{\"attributes\": [{\"row\": \"0\"}, {\"value\": \"Element Value 01\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"row\": \"1\"}, {\"value\": \"Element Value 02\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"row\": \"2\"}, {\"value\": \"Element Value 03\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"row\": \"3\"}, {\"value\": \"Element Value 04\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"row\": \"4\"}, {\"value\": \"Element Value 05\"}]}]}]}"))
}

loadJSONIntoDictionaries()

At this point, we have a bunch of Dictionaries in the jsonInterpretations variable, loaded with our test inputs. Let’s define a test output control:

let whatWeWantToSee: [String] = ["Element Value 01", "Element Value 02", "Element Value 03", "Element Value 04", "Element Value 05"]

That was easy.

A Couple of Curveballs

No so fast, Skippy. Let’s toss in a couple of curveballs for testing.

First, let’s add a “top-level” array to the test set. This would not have the container element:

{"arrayElement": [  {"value": "Element Value 01"},
                    {"value": "Element Value 02"},
                    {"value": "Element Value 03"},
                    {"value": "Element Value 04"},
                    {"value": "Element Value 05"}
                ]
}

Also, let’s mix up the order of things a bit:

{"containerElement": [  {"arrayElement": {"attributes": [{"row": 3}, {"value": "Element Value 04"}]}},
                        {"arrayElement": {"attributes": [{"row": 2}, {"value": "Element Value 03"}]}},
                        {"arrayElement": {"attributes": [{"row": 1}, {"value": "Element Value 02"}]}},
                        {"arrayElement": {"attributes": [{"row": 4}, {"value": "Element Value 05"}]}},
                        {"arrayElement": {"attributes": [{"row": 0}, {"value": "Element Value 01"}]}}
                        ]
}

And finally, we seem to have a rather…consistent set of test data. That makes our testing easier, but probably leaves some gaps. Why don’t we add another set of tests, and use different data?

{"containerElement": [  {"arrayElement": {"attributes": [{"row": 3}, {"value": 3}]}},
                        {"arrayElement": {"attributes": [{"row": 2}, {"value": "3.14"}]}},
                        {"arrayElement": {"attributes": [{"row": 1}, {"value": "0123456789!@~*&^%$#.,;:?/'"}]}},
                        {"arrayElement": {"attributes": [{"row": 4}, {"value": 1234567890}]}},
                        {"arrayElement": {"attributes": [{"row": 0}, {"value": "12345.6789"}]}}
                        ]
}

{"containerElement": [  {"arrayElement": "3"},
                        {"arrayElement": "3.14"},
                        {"arrayElement": "0123456789!@~*&^%$#.,;:?/'"},
                        {"arrayElement": "1234567890"},
                        {"arrayElement": "12345.6789"}
                        ]
}

{"containerElement": [  {"arrayElement": 3},
                        {"arrayElement": 3.14},
                        {"arrayElement": "0123456789!@~*&^%$#.,;:?/'"},
                        {"arrayElement": 1234567890},
                        {"arrayElement": 12345.6789}
                        ]
} 
jsonInterpretationsSecondaryTests.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": {\"attributes\": [{\"row\": 3}, {\"value\": 3}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": 2}, {\"value\": \"3.14\"}]}}, {\"arrayElement\": {\"attributes\": [{\"index\": 1}, {\"value\": \"0123456789!@~*&^%$#.,;:?/'\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": 4}, {\"value\": 1234567890}]}}, {\"arrayElement\": {\"attributes\": [{\"index\": 0}, {\"value\": \"12345.6789\"}]}}]}"))
jsonInterpretationsSecondaryTests.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": \"3\"}, {\"arrayElement\": \"3.14\"}, {\"arrayElement\": \"0123456789!@~*&^%$#.,;:?/'\"}, {\"arrayElement\": \"1234567890\"}, {\"arrayElement\": \"12345.6789\"}]}"))
jsonInterpretationsSecondaryTests.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": 3}, {\"arrayElement\": 3.14}, {\"arrayElement\": \"0123456789!@~*&^%$#.,;:?/'\"}, {\"arrayElement\": 1234567890}, {\"arrayElement\": 12345.6789}]}"))

This will require that we compare against different control data:

let whatWeWantToSee2: [String] = ["0123456789!@~*&^%$#.,;:?/'", "12345.6789", "1234567890", "3", "3.14"]

So now, we have a function signature (“black box”) that will ingest a [String: Any], and return a simple [String].

We also have a couple of sets of tests, ready to go, so we could totally TDD this sucker.

Onward and Upward…

SAMPLE PLAYGROUND

/*
    <containerElement>
        <arrayElement>Element Value 01</arrayElement>
        <arrayElement>Element Value 02</arrayElement>
        <arrayElement>Element Value 03</arrayElement>
        <arrayElement>Element Value 04</arrayElement>
        <arrayElement>Element Value 05</arrayElement>
    </containerElement>

    <!--
        {"containerElement": [  {"arrayElement": "Element Value 01"},
                                {"arrayElement": "Element Value 02"},
                                {"arrayElement": "Element Value 03"},
                                {"arrayElement": "Element Value 04"},
                                {"arrayElement": "Element Value 05"}
                                ]
        }

 
        {"containerElement": {"arrayElement": [ "Element Value 01",
                                                "Element Value 02",
                                                "Element Value 03",
                                                "Element Value 04",
                                                "Element Value 05"
                                                ]
                            }
        }

        {"containerElement": [  {"arrayElement": {"value": "Element Value 01"}},
                                {"arrayElement": {"value": "Element Value 02"}},
                                {"arrayElement": {"value": "Element Value 03"}},
                                {"arrayElement": {"value": "Element Value 04"}},
                                {"arrayElement": {"value": "Element Value 05"}}
                                ]
        }
    -->

    <containerElement>
        <arrayElement>
            <value>Element Value 01</value>
            <value>Element Value 02</value>
            <value>Element Value 03</value>
            <value>Element Value 04</value>
            <value>Element Value 05</value>
        </arrayElement>
    </containerElement>

    <!--
        {"containerElement": {"arrayElement": [ {"value": "Element Value 01"},
                                                {"value": "Element Value 02"},
                                                {"value": "Element Value 03"},
                                                {"value": "Element Value 04"},
                                                {"value": "Element Value 05"}
                                                ]
                            }
        }
 
        {"containerElement": {"arrayElement": [ "Element Value 01",
                                                "Element Value 02",
                                                "Element Value 03",
                                                "Element Value 04",
                                                "Element Value 05"
                                                ]
                            }
        }
    -->

    <containerElement>
        <arrayElement value="Element Value 01"/>
        <arrayElement value="Element Value 02"/>
        <arrayElement value="Element Value 03"/>
        <arrayElement value="Element Value 04"/>
        <arrayElement value="Element Value 05"/>
    </containerElement>

    <!--
        {"containerElement": [  {"arrayElement": {"attributes": [{"value": "Element Value 01"}]}},
                                {"arrayElement": {"attributes": [{"value": "Element Value 02"}]}},
                                {"arrayElement": {"attributes": [{"value": "Element Value 03"}]}},
                                {"arrayElement": {"attributes": [{"value": "Element Value 04"}]}},
                                {"arrayElement": {"attributes": [{"value": "Element Value 05"}]}}
                                ]
        }

        {"containerElement": [  {"arrayElement": {"attributes": {"value": "Element Value 01"}}},
                                {"arrayElement": {"attributes": {"value": "Element Value 02"}}},
                                {"arrayElement": {"attributes": {"value": "Element Value 03"}}},
                                {"arrayElement": {"attributes": {"value": "Element Value 04"}}},
                                {"arrayElement": {"attributes": {"value": "Element Value 05"}}}
                                ]
        }
    -->

    <containerElement>
        <arrayElement index="0">Element Value 01</arrayElement>
        <arrayElement index="1">Element Value 02</arrayElement>
        <arrayElement index="2">Element Value 03</arrayElement>
        <arrayElement index="3">Element Value 04</arrayElement>
        <arrayElement index="4">Element Value 05</arrayElement>
    </containerElement>

    <!--
        {"containerElement": [  {"arrayElement": [{"attributes": [{"index": 0}]}, {"value": "Element Value 01"}]},
                                {"arrayElement": [{"attributes": [{"index": 1}]}, {"value": "Element Value 02"}]},
                                {"arrayElement": [{"attributes": [{"index": 2}]}, {"value": "Element Value 03"}]},
                                {"arrayElement": [{"attributes": [{"index": 3}]}, {"value": "Element Value 04"}]},
                                {"arrayElement": [{"attributes": [{"index": 4}]}, {"value": "Element Value 05"}]}
                                ]
        }

        {"containerElement": [  {"arrayElement": [{"attributes": [{"index": "0"}]}, {"value": "Element Value 01"}]},
                                {"arrayElement": [{"attributes": [{"index": "1"}]}, {"value": "Element Value 02"}]},
                                {"arrayElement": [{"attributes": [{"index": "2"}]}, {"value": "Element Value 03"}]},
                                {"arrayElement": [{"attributes": [{"index": "3"}]}, {"value": "Element Value 04"}]},
                                {"arrayElement": [{"attributes": [{"index": "4"}]}, {"value": "Element Value 05"}]}
                                ]
        }

        {"containerElement": [  {"arrayElement": [{"attributes": {"index": "0"}}, {"value": "Element Value 01"}]},
                                {"arrayElement": [{"attributes": {"index": "1"}}, {"value": "Element Value 02"}]},
                                {"arrayElement": [{"attributes": {"index": "2"}}, {"value": "Element Value 03"}]},
                                {"arrayElement": [{"attributes": {"index": "3"}}, {"value": "Element Value 04"}]},
                                {"arrayElement": [{"attributes": {"index": "4"}}, {"value": "Element Value 05"}]}
                                ]
        }

        {"containerElement": [  {"arrayElement": [{"attributes": [{"index": "0"}, {"value": "Element Value 01"}]}]},
                                {"arrayElement": [{"attributes": [{"index": "1"}, {"value": "Element Value 02"}]}]},
                                {"arrayElement": [{"attributes": [{"index": "2"}, {"value": "Element Value 03"}]}]},
                                {"arrayElement": [{"attributes": [{"index": "3"}, {"value": "Element Value 04"}]}]},
                                {"arrayElement": [{"attributes": [{"index": "4"}, {"value": "Element Value 05"}]}]}
                                ]
        }
    -->

    <containerElement>
        <arrayElement row="0" value="Element Value 01"/>
        <arrayElement row="1" value="Element Value 02"/>
        <arrayElement row="2" value="Element Value 03"/>
        <arrayElement row="3" value="Element Value 04"/>
        <arrayElement row="4" value="Element Value 05"/>
    </containerElement>

    <!--
        {"containerElement": [  {"arrayElement": {"attributes": [{"row": 0}, {"value": "Element Value 01"}]}},
                                {"arrayElement": {"attributes": [{"row": 1}, {"value": "Element Value 02"}]}},
                                {"arrayElement": {"attributes": [{"row": 2}, {"value": "Element Value 03"}]}},
                                {"arrayElement": {"attributes": [{"row": 3}, {"value": "Element Value 04"}]}},
                                {"arrayElement": {"attributes": [{"row": 4}, {"value": "Element Value 05"}]}}
                                ]
        }

        {"containerElement": [  {"arrayElement": [{"attributes": [{"row": 0}, {"value": "Element Value 01"}]}]},
                                {"arrayElement": [{"attributes": [{"row": 1}, {"value": "Element Value 02"}]}]},
                                {"arrayElement": [{"attributes": [{"row": 2}, {"value": "Element Value 03"}]}]},
                                {"arrayElement": [{"attributes": [{"row": 3}, {"value": "Element Value 04"}]}]},
                                {"arrayElement": [{"attributes": [{"row": 4}, {"value": "Element Value 05"}]}]}
                                ]
        }

        {"containerElement": [  {"arrayElement": {"attributes": [{"row": "0"}, {"value": "Element Value 01"}]}},
                                {"arrayElement": {"attributes": [{"row": "1"}, {"value": "Element Value 02"}]}},
                                {"arrayElement": {"attributes": [{"row": "2"}, {"value": "Element Value 03"}]}},
                                {"arrayElement": {"attributes": [{"row": "3"}, {"value": "Element Value 04"}]}},
                                {"arrayElement": {"attributes": [{"row": "4"}, {"value": "Element Value 05"}]}}
                                ]
        }

        {"containerElement": [  {"arrayElement": [{"attributes": [{"row": "0"}, {"value": "Element Value 01"}]}]},
                                {"arrayElement": [{"attributes": [{"row": "1"}, {"value": "Element Value 02"}]}]},
                                {"arrayElement": [{"attributes": [{"row": "2"}, {"value": "Element Value 03"}]}]},
                                {"arrayElement": [{"attributes": [{"row": "3"}, {"value": "Element Value 04"}]}]},
                                {"arrayElement": [{"attributes": [{"row": "4"}, {"value": "Element Value 05"}]}]}
                                ]
        }
    -->
 */

import Foundation

func convertJSONToDictionary(_ inJSON: String) -> [String: Any] {
    do {
        if let stringData = inJSON.data(using: .utf8), let jsonDict = try JSONSerialization.jsonObject(with: stringData) as? [String: Any] {
            return jsonDict
        }
    } catch(let error) {
        print(String(describing: error))
    }
    return [:]
}

var jsonInterpretations: [[String: Any]] = []

var jsonInterpretationsSecondaryTests: [[String: Any]] = []

func loadJSONIntoDictionaries() {
    // Initial test set
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": \"Element Value 01\"}, {\"arrayElement\": \"Element Value 02\"}, {\"arrayElement\": \"Element Value 03\"}, {\"arrayElement\": \"Element Value 04\"}, {\"arrayElement\": \"Element Value 05\"}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": {\"arrayElement\": [\"Element Value 01\", \"Element Value 02\", \"Element Value 03\", \"Element Value 04\", \"Element Value 05\"]}}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": {\"value\": \"Element Value 01\"}}, {\"arrayElement\": {\"value\": \"Element Value 02\"}}, {\"arrayElement\": {\"value\": \"Element Value 03\"}}, {\"arrayElement\": {\"value\": \"Element Value 04\"}}, {\"arrayElement\": {\"value\": \"Element Value 05\"}}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": {\"arrayElement\": [{\"value\": \"Element Value 01\"}, {\"value\": \"Element Value 02\"}, {\"value\": \"Element Value 03\"}, {\"value\": \"Element Value 04\"}, {\"value\": \"Element Value 05\"}]}}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": {\"arrayElement\": [\"Element Value 01\", \"Element Value 02\", \"Element Value 03\", \"Element Value 04\", \"Element Value 05\"]}}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": {\"attributes\": [{\"value\": \"Element Value 01\"}]}}, {\"arrayElement\": {\"attributes\": [{\"value\": \"Element Value 02\"}]}}, {\"arrayElement\": {\"attributes\": [{\"value\": \"Element Value 03\"}]}}, {\"arrayElement\": {\"attributes\": [{\"value\": \"Element Value 04\"}]}}, {\"arrayElement\": {\"attributes\": [{\"value\": \"Element Value 05\"}]}}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": {\"attributes\": {\"value\": \"Element Value 01\"}}}, {\"arrayElement\": {\"attributes\": {\"value\": \"Element Value 02\"}}}, {\"arrayElement\": {\"attributes\": {\"value\": \"Element Value 03\"}}}, {\"arrayElement\": {\"attributes\": {\"value\": \"Element Value 04\"}}}, {\"arrayElement\": {\"attributes\": {\"value\": \"Element Value 05\"}}}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": [{\"attributes\": [{\"index\": 0}]}, {\"value\": \"Element Value 01\"}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": 1}]}, {\"value\": \"Element Value 02\"}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": 2}]}, {\"value\": \"Element Value 03\"}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": 3}]}, {\"value\": \"Element Value 04\"}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": 4}]}, {\"value\": \"Element Value 05\"}]}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": [{\"attributes\": [{\"index\": \"0\"}]}, {\"value\": \"Element Value 01\"}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": \"1\"}]}, {\"value\": \"Element Value 02\"}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": \"2\"}]}, {\"value\": \"Element Value 03\"}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": \"3\"}]}, {\"value\": \"Element Value 04\"}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": \"4\"}]}, {\"value\": \"Element Value 05\"}]}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": [{\"attributes\": {\"index\": \"0\"}}, {\"value\": \"Element Value 01\"}]}, {\"arrayElement\": [{\"attributes\": {\"index\": \"1\"}}, {\"value\": \"Element Value 02\"}]}, {\"arrayElement\": [{\"attributes\": {\"index\": \"2\"}}, {\"value\": \"Element Value 03\"}]}, {\"arrayElement\": [{\"attributes\": {\"index\": \"3\"}}, {\"value\": \"Element Value 04\"}]}, {\"arrayElement\": [{\"attributes\": {\"index\": \"4\"}}, {\"value\": \"Element Value 05\"}]}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": [{\"attributes\": [{\"index\": \"0\"}, {\"value\": \"Element Value 01\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": \"1\"}, {\"value\": \"Element Value 02\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": \"2\"}, {\"value\": \"Element Value 03\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": \"3\"}, {\"value\": \"Element Value 04\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"index\": \"4\"}, {\"value\": \"Element Value 05\"}]}]}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": {\"attributes\": [{\"row\": 0}, {\"value\": \"Element Value 01\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": 1}, {\"value\": \"Element Value 02\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": 2}, {\"value\": \"Element Value 03\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": 3}, {\"value\": \"Element Value 04\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": 4}, {\"value\": \"Element Value 05\"}]}}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": [{\"attributes\": [{\"row\": 0}, {\"value\": \"Element Value 01\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"row\": 1}, {\"value\": \"Element Value 02\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"row\": 2}, {\"value\": \"Element Value 03\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"row\": 3}, {\"value\": \"Element Value 04\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"row\": 4}, {\"value\": \"Element Value 05\"}]}]}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": {\"attributes\": [{\"row\": \"0\"}, {\"value\": \"Element Value 01\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": \"1\"}, {\"value\": \"Element Value 02\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": \"2\"}, {\"value\": \"Element Value 03\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": \"3\"}, {\"value\": \"Element Value 04\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": \"4\"}, {\"value\": \"Element Value 05\"}]}}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": [{\"attributes\": [{\"row\": \"0\"}, {\"value\": \"Element Value 01\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"row\": \"1\"}, {\"value\": \"Element Value 02\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"row\": \"2\"}, {\"value\": \"Element Value 03\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"row\": \"3\"}, {\"value\": \"Element Value 04\"}]}]}, {\"arrayElement\": [{\"attributes\": [{\"row\": \"4\"}, {\"value\": \"Element Value 05\"}]}]}]}"))
    
    // Extra Credit
    jsonInterpretations.append(convertJSONToDictionary("{\"arrayElement\": [{\"value\": \"Element Value 01\"}, {\"value\": \"Element Value 02\"}, {\"value\": \"Element Value 03\"}, {\"value\": \"Element Value 04\"}, {\"value\": \"Element Value 05\"}]}"))
    jsonInterpretations.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": {\"attributes\": [{\"row\": 3}, {\"value\": \"Element Value 04\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": 2}, {\"value\": \"Element Value 03\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": 1}, {\"value\": \"Element Value 02\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": 4}, {\"value\": \"Element Value 05\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": 0}, {\"value\": \"Element Value 01\"}]}}]}"))
    
    // Differing Data
    jsonInterpretationsSecondaryTests.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": {\"attributes\": [{\"row\": 3}, {\"value\": 3}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": 2}, {\"value\": \"3.14\"}]}}, {\"arrayElement\": {\"attributes\": [{\"index\": 1}, {\"value\": \"0123456789!@~*&^%$#.,;:?/'\"}]}}, {\"arrayElement\": {\"attributes\": [{\"row\": 4}, {\"value\": 1234567890}]}}, {\"arrayElement\": {\"attributes\": [{\"index\": 0}, {\"value\": \"12345.6789\"}]}}]}"))
    jsonInterpretationsSecondaryTests.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": \"3\"}, {\"arrayElement\": \"3.14\"}, {\"arrayElement\": \"0123456789!@~*&^%$#.,;:?/'\"}, {\"arrayElement\": \"1234567890\"}, {\"arrayElement\": \"12345.6789\"}]}"))
    jsonInterpretationsSecondaryTests.append(convertJSONToDictionary("{\"containerElement\": [{\"arrayElement\": 3}, {\"arrayElement\": 3.14}, {\"arrayElement\": \"0123456789!@~*&^%$#.,;:?/'\"}, {\"arrayElement\": 1234567890}, {\"arrayElement\": 12345.6789}]}"))
}

loadJSONIntoDictionaries()

let whatWeWantToSee: [String] = ["Element Value 01", "Element Value 02", "Element Value 03", "Element Value 04", "Element Value 05"]
let whatWeWantToSee2: [String] = ["0123456789!@~*&^%$#.,;:?/'", "12345.6789", "1234567890", "3", "3.14"]

func myParser(_ inDictionaryToBeParsed: [String: Any]) -> [String] {
   return []
}