关闭扁平嵌套对象?

时间:2016-04-13 17:33:12

标签: arrays swift closures

我开始学习关闭,并希望在我正在开发的项目中实现它们,我想要一些帮助。

我的课程定义如下:

class MyObject {
var name: String?
var type: String?
var subObjects: [MyObject]?
}

我想使用闭包或更高级的函数(类似于flatMap)来展平[MyObject]并将所有MyObjectsubOjects加入到一个数组中

我尝试过使用[MyObject].flatMap(),但此操作不会返回嵌套的子对象。

2 个答案:

答案 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本地功能。它将嵌套对象的内容附加到结果中,然后有条件地为每个元素调用自己以添加其内容。