将具有深度值的记录数组映射到嵌套的无序列表

时间:2010-02-24 04:18:43

标签: ruby-on-rails arrays mapping html-lists

我希望以前没有问过这个问题:

我正在使用祖先gem来管理我的树结构。我正在使用一个函数,它将节点的后代返回到一定数量的级别。这是一个简单的例子,说明它的回归:

[{:name => 'node 1', :depth => 1}, {:name => 'node 2', :depth => 2}
 {:name => 'node 3', :depth => 1}, {:name => 'node 4', :depth => 1}]

实际上,这些是正确排序的记录,以便记录的所有子孙,孙等等出现在该记录之后,因此我们可以假设“节点2”是“节点1”的子节点。我们还可以使用该方法返回的额外信息来证明这一点,我在此示例中未包含这些信息以使其更简单。

我想以最有效的方式将其变成无序列表:

<ul>
  <li>node 1
    <ul>
      <li>node 2</li>
    </ul>
  </li>
  <li>node 3</li>
  <li>node 4</li>
</ul>

这就是我被困住的地方。具有如上所述的有序数组值对于避免通常需要用于生成nester无序列表的递归代码是很好的。我想也许只是简单地映射数组的成员并插入适当的UL和LI将是最快的方式?

期待看到您的想法!

布伦登

1 个答案:

答案 0 :(得分:1)

这个ERB模板应该可以解决问题。将代码提取到帮助程序或部分提取整齐。

<%
# lets assume that your array is an a variable
# called list
list = [ {:name => 'node 1', :depth => 1}, 
         {:name => 'node 2', :depth => 2},
         {:name => 'node 3', :depth => 1}, 
         {:name => 'node 4', :depth => 1}]

%>
<% depth = 1%>
<ul>
<%list.each do |cfg|%>
  <%if depth < cfg[:depth] %> 
    <ul>
  <%elsif depth > cfg[:depth] %>
      <%
      # take care of the free fall
      (depth - cfg[:depth]).times do
      %>
        </ul>   
      <%end%>
  <%end%>
  <li> <%= cfg[:name] %></li>
  <%depth = cfg[:depth] %>
<%end%>
<%
# take care of the final free fall 
depth.times do 
%>
  </ul>
<%end%>