6

If my tree is defined as such:

case class Node(value: Int, children: Seq[Node])

but for the sake of the argument, let's say that accessing the children are expensive such that I want to traverse them only when I actuall need to.

If a non-strict, eager DFS traversal on Node is defined as

def traverse(node: Node): Unit = {
  node.children foreach { child => traverse(child) }
}

How do I create a lazy counterpart of it?

Ideally I will have an iterator method which returns an iterator based on DFS traversal ordering that only evaluates the next element when next() is called on it:

val tree = Node(1, Seq(Node(2, Nil), Node(3, Nil)))
val dfsIt = tree.iterator // get a iterator with a DFS traversal ordering
val nextNode = dfsIt.next() // compute which element to return on demand
lolski
  • 16,231
  • 7
  • 34
  • 49

1 Answers1

3
case class Node(value: Int, children: Seq[Node]) {

  def dfsIterator: Iterator[Node] = {
    println(value)
    children.iterator.map(_.dfsIterator).flatten ++ Iterator(this)
  }
}
thirstycrow
  • 2,806
  • 15
  • 18
  • This is very elegant. The only improvement would be to replace `map...flatten` with `flatMap`. (Was it not available in 2015?) – Igor Urisman Jan 12 '23 at 04:45