Scala - 递归函数不返回对象

pla*_*oom 0 recursion scala

我有以下对象结构:

case class Node(id:Int,children:List[Node])
Run Code Online (Sandbox Code Playgroud)

例:

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: []
                    ]

            ]
        ...
Run Code Online (Sandbox Code Playgroud)

我想创建一个递归循环来获取具有特定Id的Node,但是如果找不到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
}           
Run Code Online (Sandbox Code Playgroud)

Kol*_*mar 7

函数getNode确实应该返回Option[Node]到帐户中搜索树中id缺少的内容Node.

在这种情况下,您可以组成递归调用的选项:

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

在命令性的情况下,您不需要检查列表长度:只需返回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
  }
} 
Run Code Online (Sandbox Code Playgroud)

对于Java,您当然可以替换Optionnull,但在Scala中,这个想法自然是由模型构建的Option