如何获得递归方法来获取非参数,阻止并在每个循环调用上运行它?

How do I get a recursive method to take a, non argument, block and run it on each recurrent call?

提问人:jbk 提问时间:4/27/2023 最后编辑:jbk 更新时间:4/27/2023 访问量:42

问:

我正在尝试首先编写一个递归二叉树深度,预排序,遍历方法,并在通过一个块时也让它工作。但是我正在努力弄清楚如何让它使用从每个内部循环调用的初始调用到自身的传递块。我目前编写的代码是:

  def pre_order(node = @root, values = [])
    return values if node.nil?
    block_given? ? values << yield(node.value) : values << node.value
    pre_order(node.left, values) if node.left
    pre_order(node.right, values) if node.right
    values
  end

在不传递块的情况下调用我的测试树对象会返回这个正确的输出; .但是,当我调用并传递一个块时,例如; 我得到的结果,与我的目标结果是;#pre_order[7, 1, 4, 65, 13, 97]#pre_order#pre_order { |value| value * 2 }

上述代码的结果; 我的目标是结果;[14, 1, 4, 65, 13, 97][14, 2, 8, 130, 26, 194]

我想最好的方法可能是以某种方式将最初传递的块保存在变量中,以便它可以在第 4 行和第 5 行的递归方法调用中再次使用它,而不会丢失或需要在每次方法调用时重置它。如何做到这一点?(我有一种感觉,我在这里处于 Proc 领域,并且正在进一步研究这个问题,但希望能得到一些关于“Ruby 方式”的指导。

Ruby 方法 proc

评论


答:

3赞 Stefan 4/27/2023 #1

您必须显式定义 block 参数并传递它:

def pre_order(node = @root, values = [], &block)
  # ...
  pre_order(node.left, values, &block) if node.left
  pre_order(node.right, values, &block) if node.right
  # ...
end

使用显式块参数,还可以替换为更显式或速记语法。(注意括号前的)yield(node.value)block.call(node.value)block.(node.value).

评论

0赞 jbk 4/27/2023
谢谢你@stefan。开始看到 \s 操作员/对象的机制,我想,这要归功于您的回答!&:{}Proc