I am receiving a JSON:
{
"categories":
[
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
...
As can be seen, the data is a recursive format. I was able to write the code for decoding it into my custom type which is:
struct Name: Codable {
let cat: String
let children: [cat]?
}
Now, for any cat, I would like to know the "path" of it. As in, I’d like know what are all the super(ancestor) categories. So, for the category "tablets", I would like to be able to traverse what the drill down structure looks like, which in this case could look like:
Electronics -> Computers -> Laptops and Tablets -> Tablets
How do I structure my code or data model to be able to retrieve this information for any category?
3
Answers
Here is a basic recursive solution that adds the path of elements to an array with the root element as the first and the targeted element as the last.
It uses
contains()
soCategory
needs to conform toEquatable
or it could be changed to use `contains(where:) instead likeif it is a more practical solution.
I’ve only made some basic tests, one with a match the 3rd level down and one with no match so some further testing is probably needed.
You can use class and ancestor like this :
You can change the order and/or return only categoryName in the list
EDIT : corrected the code
First, you’ll want to add the path to Category so you have somewhere to store the data. For convenience, I’ll also add a CategoriesResponse just to handle the top-level structure, but it’s not really important:
(I’m assuming what you want are just the names of the parent categories. If you want references of some kind, that’s possible, but the data structures get a little more complicated. This basic approach will still work, though. Let me know if you need something like that, and I can expand the answer.)
And of course standard CodingKeys stuff:
The meat of the solution is that you need an init that can accept a KeyedDecodingContainer (rather than a Decoder) and a path, and handle decoding everything else.
And finally, you need a Decodable implementation just to kick it all off:
With that, it should work as expected using a standard Decoder: