如何使函数采用树文字?

时间:2016-12-27 19:18:01

标签: swift tree

我希望能够将任意嵌套的元组或数组传递给树构建器函数,如下所示:

 /**     
 Data Types Conversions:
 -----------------------
 +-----------------+-------------+
 | kernel          | Swift/Obj-c |
 +=================+=============+
 | sampler         | CISampler   |
 | __table sampler | CISampler   |
 | __color         | CIColor     |
 | float           | NSNumber    |
 | vec2/3/4        | CIVector    |
 +-----------------+-------------+
 */

如何为这样的功能编写签名?

make_tree( (l: nil, v: 1, r:(l:(r: nil, v: 5, r: nil), v: 8, r: nil)) )

3 个答案:

答案 0 :(得分:3)

如果您只是声明一个Node类,那么

class Node {
    var left: Node?
    var right: Node?
    var value: Int

    init(left: Node?, value: Int, right:Node?) {
        self.left = left
        self.right = right
        self.value = value
    }
}

然后你可以写

let tree = Node(left: nil, value: 1, right: Node(left: Node(left: nil, value: 5, right: nil), value: 8, right: nil))

更新

你也可以像这样使用default value初始化程序的参数

class Node {
    var left: Node?
    var right: Node?
    var value: Int

    init(left: Node? = nil, value: Int, right:Node? = nil) {
        self.left = left
        self.right = right
        self.value = value
    }
}

现在,当您想要将left值传递给它们时,您可以构建相同的树,省略rightnil参数。

let tree = Node(value: 1, right: Node(left: Node(value: 5), value: 8))

答案 1 :(得分:1)

我会使用枚举。

class Tree<T> {
    var root: Node<T>
    init(_ root: Node<T>) { self.root = root}
}

indirect enum Node<T> {
    case branch(Node, value: T, Node)
    case leftBranch(left: Node, value: T)
    case rightBranch(value: T, right: Node)
    case leaf(value: T)
}

func makeTree() -> Tree<Int> {
    return Tree(.rightBranch(value: 1, right:
        .leftBranch(left: .leaf(value: 5), value: 8)))
}

答案 2 :(得分:0)

您可以简单地解析字典文字。

class TreeClass {
    var left: TreeClass?
    var right: TreeClass?
    var value: Int

    init(left: TreeClass?, right: TreeClass?, value: Int) {
        self.left = left
        self.right = right
        self.value = value
    }
}

extension TreeClass {
    enum Key {
        case left
        case right
        case value
    }
}

func makeTree(_ tree: [TreeClass.Key: Any]) -> TreeClass {
    var left: TreeClass?
    var right: TreeClass?
    var value: Int?
    for (key, dictValue) in tree {
        switch (key, dictValue) {
        case (.left, let nodeValue as [TreeClass.Key: Any]):
            assert(left == nil)
            left = makeTree(nodeValue)
        case (.right, let nodeValue as [TreeClass.Key: Any]):
            assert(right == nil)
            right = makeTree(nodeValue)
        case (.value, let intValue as Int):
            assert(value == nil)
            value = intValue
        default:
            fatalError()
        }
    }
    assert(value != nil)
    return TreeClass(left: left, right: right, value: value!)
}

let v = TreeClass.Key.value
let r = TreeClass.Key.right
let l = TreeClass.Key.left

let tree = makeTree([v: 1, r: [l: [v: 5], v: 8]])

我也曾尝试使用ExpressibleByDictionaryLiteralExpressibleByArrayLiteral,但有些部分对我来说太丑了。

坦率地说,我,我自己会写一些类似于appzYourLife的东西,它是类型安全的,简单易懂的。