我开始学习关闭,并希望在我正在开发的项目中实现它们,我想要一些帮助。
我的课程定义如下:
class MyObject {
var name: String?
var type: String?
var subObjects: [MyObject]?
}
我想使用闭包或更高级的函数(类似于flatMap
)来展平[MyObject]
并将所有MyObject
和subOjects
加入到一个数组中
我尝试过使用[MyObject].flatMap()
,但此操作不会返回嵌套的子对象。
答案 0 :(得分:4)
首先,我强烈建议将subObjects
的类型设为非可选。可选数组很少有理由。你真的需要区分"没有阵列"和#34;一个空数组?"这非常罕见。如果你使subObjects
只是一个数组,你可以将你描述的内容写成一个简单的递归函数:
func flattenMyObjects(myObjects: [MyObject]) -> [MyObject] {
return myObjects.flatMap { (myObject) -> [MyObject] in
var result = [myObject]
result.appendContentsOf(flattenMyObjects(myObject.subObjects))
return result
}
}
如果您需要它是可选的,则更改很小(您需要添加if-let或类似的东西)。
答案 1 :(得分:2)
展平递归类结构的一种方法是使用递归函数。
这是我们想要展平的课程:
public class Nested {
public let n : Int
public let sub : [Nested]?
public init(_ n:Int, _ sub:[Nested]?) {
self.n = n
self.sub = sub
}
}
以下是演示如何完成此操作的函数:
func test() {
let h = [
Nested(1, [Nested(2, nil), Nested(3, nil)])
, Nested(4, nil)
, Nested(5, [Nested(6, nil), Nested(7, [Nested(8, nil), Nested(9, nil)])])
]
func recursiveFlat(next:Nested) -> [Nested] {
var res = [Nested]()
res.append(next)
if let subArray = next.sub {
res.appendContentsOf(subArray.flatMap({ (item) -> [Nested] in
recursiveFlat(item)
}))
}
return res
}
for item in h.flatMap(recursiveFlat) {
print(item.n)
}
}
这种方法的核心是recursiveFlat
本地功能。它将嵌套对象的内容附加到结果中,然后有条件地为每个元素调用自己以添加其内容。