所以这似乎是一个简单的问题,但我很难找到解决方案。
我有一个页面列表,一些页面有子页面,其中一些子页面有自己的子页面。我想创建一种按照子页面顺序列出所有页面的方法。
我的目标是这个输出:
page_1
page_1a
page_2
page_2a
page_2b
page_2bi
page_2bii
page_2biii
page_2c
page_3
page_4
page_5
(我正在寻找的实际输出是一个数组,然后我可以在我的视图中打印出来。)
如果我使用嵌套的each
语句,这将非常容易,但我想要一些与嵌套深度无关的东西。无论嵌套的级别数是多少,我都需要能产生正确输出的东西。
我已经找到了解决方案,并提出了以下代码。这段代码的问题在于,一旦它嵌入,它就找不到嵌套页面的父级的剩余兄弟 - 换句话说,它在找到嵌套页面后停止并移动到下一个顶级页面。 / p>
def print_page_hierarchy
output = []
Page.top_level.each do |p|
level = 0
keep_looping = true
output << [p.title]
while keep_looping
if p.children?
level += 1
nested_pages = p.children
for p in nested_pages
output << [" "*(level*2)+p.title]
if p.children?
nested_pages = p.children # p.children returns an array of child pages
keep_looping = true
break
end
end
else
keep_looping = false
end
end
end
output
end
我该如何使这项工作?
或者有更好的方法来解决这个问题吗?
修改
输入是一系列关联。页面包含parent_page_id,其方法为parent
和children
。我没有初始数组,只有关联。
这并不重要,因为问题是如何处理递归。为简单起见,您可以假设这是一个数组。
答案 0 :(得分:1)
准备一些输入。我假设你有一个节点数组,每个节点都有一个名字和子节点:
class Node < Struct.new(:name, :children); end
nodes = [ Node.new(:page_1, [ Node.new(:page_1a) ]),
Node.new(:page_2, [ Node.new(:page_2a),
Node.new(:page_2b, [ Node.new(:page_2bi),
Node.new(:page_2bii),
Node.new(:page_2biii) ]),
Node.new(:page_2c) ]),
Node.new(:page_3),
Node.new(:page_4),
Node.new(:page_5) ]
递归方法:
def print_page_hierarchy(nodes, indent = 0)
return unless nodes # stops the recursion if there are no nodes
nodes.each do |node|
puts "#{' ' * indent}#{node.name}"
# here is the list of all children generated, do not care about how
# deep the subtree is, cause recursion...
print_page_hierarchy(node.children, indent + 1)
end
end
测试
print_page_hierarchy(nodes)
# => page_1
# page_1a
# page_2
# page_2a
# page_2b
# page_2bi
# page_2bii
# page_2biii
# page_2c
# page_3
# page_4
# page_5