How can I build a recursive function in Swift to return a String?

Viewed 387

I have a Node class defined as follows. value: T is a String

class Node<T> {
    var value: T
    weak var parent: Node?
    var children = [Node<T>]()
    init(_ value: T) {
        self.value = value
    }
    func add(_ node: Node<T>) {
        children.append(node)
        node.parent = self
    }
}

I'd like to build a function to return a String of the current Node's value and all Parent values. Ideally, the function would be defined in the class. For example,

currentnode.listAllValues()
would return -> "/parent2value/parent1value/currentnodevalue"

So far the following function works with a simple print(), and I've also considered using an inout parameter.

func listAllValues(node: Node<String>) {
    print(node.value)
    if node.parent?.value != nil {
        listAllValues(node: node.parent!)
    }
}
2 Answers

You can achieve this with an instance method which calls itself on the parent node first, if there is one:

func listAllValues() -> String {
    if let p = parent {
        return "\(p.listAllValues())/\(value)"
    } else {
        return "/\(value)"
    }
}

Or as an obfuscated one-liner:

func listAllValues() -> String {
    return "\(parent?.listAllValues() ?? "")/\(value)"
}

Example:

let p2 = Node("parent2value")
let p1 = Node("parent1value") ; p2.add(p1)
let n = Node("currentNodeValue") ; p1.add(n)

print(n.listAllValues())
// --> /parent2value/parent1value/currentNodeValue

Here you go:

func desc(_ s:String? = nil) -> String {
    var me = String(describing:self.value)
    if let prev = s {
        me += "/" + prev
    }
    return self.parent?.desc(me) ?? me
}

Example:

let n = Node("hey")
n.add(Node("ho"))
n.children.first?.add(Node("nonny nonny no"))
let start = n.children.first!.children.first!
print(start.desc())
Related