Mapping an array of records with depth values into nested Unordered List
I hope this question hasn't been asked before:
I'm using the ancestry gem to manage my tree structure. I'm using a function which returns the descendants of a node to a certain number of levels. Here's a simplistic example of what it's returning:
[{:name => 'node 1', :depth => 1}, {:name => 'node 2', :depth => 2}
{:name => 'node 3', :depth => 1}, {:name => 'node 4', :depth => 1}]
In reality those are records ordered correctly so that all the children, grandchildren etc... of a record appear after that record, so we can assume that 'node 2' is the child of 'node 1'. We can also prove this with the extra information that the method returns which I haven't included in this example to make it simpler.
I'm wanting to turn this into an unordered list in the most efficient manner possible:
<ul>
<li>node 1
<ul>
<li>node 2</li>
</ul>
</li>
<li>node 3</li>
<li>node 4</li>
</ul>
And that's where I'm st开发者_开发问答uck. Having an ordered array of values like the above is great for avoiding the recursive code one normally needs to use to produce a nester unordered list. I'm thinking that perhaps simply mapping the members of the array and inserting the appropriate UL's and LI's would be the quickest way to go?
Looking forward to seeing your ideas!
Brendon
This ERB template should do the trick. Extract the code to a helper or a partial for tidiness.
<%
# 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%>
精彩评论