2015-02-10 60 views
0

我有以下对象结构:斯卡拉 - 递归函数不返回对象

case class Node(id:Int,children:List[Node]) 

例子:

NodeA 
    id: 1 
    children:[ 
     NodeA1: 
      id: 2 
      children: 
       NodeA11 
       ... 
     ]  
     NodeB1: 
      id: 3 
      children:[] 
     NodeC1: 
      id: 17 
      children: [ 
       NodeC11: 
        id:11 
        children:[ 
         NodeC111: 
          id: 19 
          children: [] 
        ] 

      ] 
     ... 

我想创建一个递归循环,从而得到具有特定的节点Id,但我卡在如何保持运行功能,如果没有找到iD,并且该对象在儿童列表上有任何对象。我的功能只能用于获取第一个节点(例如:Id = 1)。

这里就是我想要做的事:

def getNode(id:Int, node:Node) : Node = { 
    var result:Node = null 
    if(node.id == id){ 
     return node 
    } else if(node.children.size > 0){ 
     for(children <- node.children){ 
     result = getNode(id, children) 
     if(result.id == id){ 
      return result 
     } 
     } 
    } 
    return result 
}   
+0

仿照你真想当什么也没找到,返回'null'? – Bergi 2015-02-10 16:53:55

+0

它可能为空,无或异常 – placplacboom 2015-02-10 16:55:14

回答

7

功能getNode真的应该返回Option[Node]占搜索的idNode树不见了。

而且在这种情况下,你可以编写递归调用的选项:

def getNode(id:Int, node:Node): Option[Node] = 
    if (node.id == id) Some(node) 
    else node.children.collectFirst(Function.unlift(getNode(id, _))) 

在必要的情况下,你不需要为列表长度检查:只返回None/null,你检查每一个孩子在循环之后(或者不要检查是否没有任何孩子)。

def getNode(id:Int, node:Node) : Option[Node] = { 
    if (node.id == id) Some(node) 
    else { 
    for (child <- node.children) { 
     val result = getNode(id, child) 
     // At this point `result` is Some(nodeWeAreLookingFor) 
     // if it is in the subtree of the current `child` 
     // or None otherwise 
     if (result.isDefined) return result 
    } 
    None 
    } 
} 

对于Java你当然可以取代Optionnull,但在斯卡拉这个想法,自然是Option

+0

那么优雅......我只是想知道,如何编写其他条件的命令?我在问,因为我是java开发人员,我想在这些语言上做一个并行工作 – placplacboom 2015-02-10 17:05:39

+0

@placplacboom我已经为命令性案例添加了一部分 – Kolmar 2015-02-10 17:23:02

+0

真棒并感谢您在for循环内帮助 – placplacboom 2015-02-10 17:26:29