I am receiving a JSON:
{
"categories":
[
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name"
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name"
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name"
}
]
},
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"category_name": "example name",
"children":
[
{
"category_name": "example name"
},
{
"category_name": "example name"
},
{
"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 Category: Codable {
let categoryName: String
let children: [Category]?
}
Now, for any category, 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?
CodePudding user response:
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()
so Category
needs to conform to Equatable
or it could be changed to use `contains(where:) instead like
contains(where: { $0.categoryName == target.categoryName })
if it is a more practical solution.
func extractChain(for target: Category, parent: Category, chain: inout [Category]) {
guard let children = parent.children else {
chain = []
return
}
chain.append(parent)
if children.contains(target) {
chain.append(target)
return
}
for category in children where category.children != nil {
extractChain(for: target, parent: category, chain: &chain)
if !chain.isEmpty { return }
}
chain = [] // No match, clear the array
}
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.
CodePudding user response:
You can use class and ancestor like this :
class Category: Codable {
let categoryName: String
let children: [Category]?
var parentCategory: Category?
func setupAncestors(ancestor: Category?) {
category.ancestor = ancestor
for child in children {
setupAncestor(ancestor: self, forCategory: child)
}
func ancestors() [Category] {
if let ancestor = ancestor {
var ancestorList = [ancestors]
ancestorList.append(contentsOf: ancestor.ancestorList ()
return ancestorList
}
return []
}
}
You can change the order and/or return only categoryName in the list