Reputation: 109
I have a recursive function which collects the leaf nodes of a kd-tree. This function has to take KdNode as an argument. The KdNode has the following class definition:
case class KdNode(value: (Double, Double), left: Option[KdNode], right: Option[KdNode], axis: Int, BB_A:BoundingBox, BB_B:BoundingBox)
The function definition where it is taken as an argument is:
def collectLeafNodes(t:KdNode): List[BoundingBox] = {
if(t == None) return
if (t.left == None && t.right == None) {
Some(listBoundingBox.::(t.BB_A,t.BB_B))
return
}
collectLeafNodes(t.left)
collectLeafNodes(t.right)}
Here, I encounter error on the last 2 lines saying: "Type mismatch, expected: KdNode, actual: Option[KdNode].
I am calling this function by building the kd-tree in variable "tree" and giving it as an argument:
val listofBoundingBoxes=collectLeafNodes(tree)
What is a possible workaround in this situation? In addition, I think there should be a way to pass the root node instead of tree to the collectLeafNodes function, is that possible given the tree is built in a separate function.
Thanks.
Upvotes: 0
Views: 67
Reputation: 51271
You ask, in the comments, how it can be done without return
. Here's one way.
def collectLeafNodes(t :KdNode) :List[BoundingBox] =
List(t.BB_A, t.BB_B) :::
t.left.fold(List.empty[BoundingBox])(collectLeafNodes) :::
t.right.fold(List.empty[BoundingBox])(collectLeafNodes)
The result, without return
, is the concatenation of 3 lists:
t
is a KdNode
and not an Option[KdNode]
, we know that the the BB
values are real. That's the 1st List
.t.left
is None
then the 2nd List
is empty, otherwise the 2nd List
is whatever the recursive call to collectLeafNodes(t.left)
returns. (The argument is automatically supplied so it need not be specified.)List
with t.right
corrected for leaf nodes only
def collectLeafNodes(t :KdNode) :List[BoundingBox] = {
if (t.left.isEmpty && t.right.isEmpty) List(t.BB_A, t.BB_B)
else t.left .fold(List.empty[BoundingBox])(collectLeafNodes) :::
t.right.fold(List.empty[BoundingBox])(collectLeafNodes)
}
Upvotes: 3
Reputation: 3191
You can map over the option object:
val res: List[BoundingBox] = t.left.map(collectLeafNodes).getOrElse(List())
Upvotes: 2
Reputation: 717
Because t.right is type of Option and not type of Kdnode.
You can unwrap Option to solve this e.g.
collectLeafNodes(t.right.get)}
collectLeafNodes(t.right.orElse(None)}
Hope this helps
Upvotes: 0