如上所述,我编写了一个类,它允许您遍历一组分层数据,同时保持该层次结构的有序性。通过指定根元素和返回每个根的子元素的闭包,可以做到这一点。通过递归,实现不仅以正确的层次顺序返回内容,而且还返回一个级别,这样您就知道这些项的深度了。
这是密码……
struct HierarchicalSequence<TItem> : Sequence {
typealias GetChildItemsDelegate = (TItem) -> [TItem]
init(rootItems:[TItem], getChildItems: GetChildItemsDelegate? = nil){
self.rootItems = rootItems
self.getChildItems = getChildItems
}
let rootItems : [TItem]
let getChildItems : GetChildItemsDelegate?
class Iterator : IteratorProtocol {
typealias Element = (level:Int, item:TItem)
init(level:Int, items:[TItem], getChildItems: GetChildItemsDelegate? = nil){
self.level = level
self.items = items
self.getChildItems = getChildItems
}
let level : Int
let items : [TItem]
let getChildItems : GetChildItemsDelegate?
private var nextIndex = 0
var childIterator:Iterator?
func next() -> Element? {
if let childIterator = childIterator {
if let childIteratorResult = childIterator.next(){
return childIteratorResult
}
self.childIterator = nil
}
if nextIndex == items.count {
return nil
}
let item = items[nextIndex]
nextIndex += 1
if let getChildItems = getChildItems {
let childItems = getChildItems(item)
childIterator = Iterator(
level : level + 1,
items : childItems,
getChildItems : getChildItems)
}
return (level, item)
}
}
func makeIterator() -> Iterator {
return Iterator(level: 0, items: rootItems, getChildItems: getChildItems)
}
}
下面是一个使用它的例子。
public let jsonString = """
[
{
"name" : "Section A",
"subCategories" : [
{
"name" : "Category A1",
"subCategories" : [
{ "name" : "Component A1a" },
{ "name" : "Component A1b" }
]
},
{
"name" : "Category A2",
"subCategories" : [
{ "name" : "Component A2a" },
{ "name" : "Component A2b" }
]
}
]
},
{
"name" : "Section B",
"subCategories" : [
{
"name" : "Category B1",
"subCategories" : [
{ "name" : "Component B1a" },
{ "name" : "Component B1b" }
]
},
{
"name" : "Category B2",
"subCategories" : [
{ "name" : "Component B2a" },
{ "name" : "Component B2b" }
]
}
]
}
]
"""
public let jsonData = jsonString.data(using: .utf8)!
class Category : Codable {
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decode(String.self, forKey: .name)
subCategories = try values.decodeIfPresent([Category].self, forKey: .subCategories) ?? []
}
let name : String
let subCategories : [Category]
}
var myJsonCategories = try! JSONDecoder().decode([Category].self, from: jsonData)
let hierarchicalCategories = HierarchicalSequence(rootItems:myJsonCategories){
category in category.subCategories
}
for categoryInfo in hierarchicalCategories {
print("\(String(repeating: " ", count: categoryInfo.level * 2))\(categoryInfo.level):\(categoryInfo.item.name)")
}
最后,这里是输出…
0:Section A
1:Category A1
2:Component A1a
2:Component A1b
1:Category A2
2:Component A2a
2:Component A2b
0:Section B
1:Category B1
2:Component B1a
2:Component B1b
1:Category B2
2:Component B2a
2:Component B2b
我很想得到一些反馈,看看是否有一个更容易的方法来实现这一点,但我不得不说,我对性能很满意。
让我知道你的想法!