新手轨道逻辑&语法问题

时间:2014-11-09 21:02:20

标签: ruby-on-rails

我正在学习rails并且遇到了我想要使用的以下代码。有问题的代码是John F Miller(第一个答案)在以下链接中的答案: How to render all records from a nested set into a real html tree

def tree_from_set(set) #set must be in order
  buf = START_TAG(set[0])
  stack = []
  stack.push set[0]
  set[1..-1].each do |node|
    if stack.last.lft < node.lft < stack.last.rgt
      if node.leaf? #(node.rgt - node.lft == 1)
        buf << NODE_TAG(node)
      else
        buf << START_TAG(node)
        stack.push(node)
      end
    else#
      buf << END_TAG
      stack.pop
      retry
    end
  end
  buf <<END_TAG
end

def START_TAG(node) #for example
  "<li><p>#{node.name}</p><ul>"
end

def NODE_TAG(node)
  "<li><p>#{node.name}</p></li>"
end

def END_TAG
  "</li></ul>"
end

我不确定以下情况,并希望得到任何指导。

我看到这将循环“set”将每个项目分配给对象“node”但是我无法确定[1 ..- 1]的作用。

set[1..-1].each do |node|

遵循逻辑我无法理解从数组“stack”中删除最后一项的目的

stack.pop

在1.9之后的ruby中不再支持此上下文中的此命令。我相信目的是回到循环的开始并重复。

retry

1 个答案:

答案 0 :(得分:1)

A&#34;子阵列&#34;除了第0个元素之外的所有元素。

Ruby中的负数组索引-xlength-x的缩写。也就是说,-1&#39; st元素是最后一个元素。范围1..-1是&#34;首先是#34;但由于数组在Ruby中为零索引,这意味着&#34;除了第0个元素之外的所有元素&#34;。

堆栈保持&#34;你有多深&#34;,更确切地说,你目前在哪些元素。当检查下一个元素时,如果你&#34;熄灭&#34;,你应该关闭在添加当前项目之前列出你离开(可能是多次!)。

至于retry:我认为它应该是redo。如果你走出去,你必须确保你关闭你所拥有的每个列表:每次迭代从堆栈中弹出一次,关闭最近的列表并循环它,直到你在堆栈的顶部元素内,在上下文中要插入的当前节点。

实际上,代码假设您只有一棵树set[0]的根。通过向第6行添加一个检查(使用||),如果堆栈为空,则消除此缺陷,需要手动推送set[0],从而将其从循环中排除。 因为如果堆栈是空的,那么你处于包含所有内容的超空间,所以你不应该费心去比较任何东西。这使您可以从一个列表中呈现多个元素树(可能没有共同的根)。

我相信对此的清洁解决方案是一个递归的解决方案,取代&#34;自制堆栈&#34;使用Ruby的调用堆栈。尽管如此,我无法在这方面做出太快的解决方案。