views:

222

answers:

1

I have an array of paths, array = [ 'a.txt', 'b/a.txt', 'a/a.txt', 'a/z/a.txt' ]

I need to create a tree structure (for the jTree plugin), but it has to be sorted by folders first (alphabetically) and then leafs (alphabetically too).

A sorted tree structure with the above example would look like this:

  • a
    • z
      • a.txt
    • a.txt
  • b
    • a.txt
  • a.txt

EDIT: Im looking to build a Tree of HTML ordered lists and list items, where each node is a LI and if its a folder it has another UL as a sibling. This is one of the formats the jTree plugin takes as input. Structure for above example:

<ul>
  <li class="folder">a</li>
  <ul>
    <li class="folder">z</li>
    <ul>
      <li class="leaf">a.txt</li>
    </ul>
  </ul>
  <li class="folder">b</li>
  <ul>
    <li class="leaf">a.txt</li>
  </ul>
  <li class="leaf">a.txt</li>
</ul>

This will build the tree structure as a hash tree:

array = ["home", "about", "about/history", "about/company", "about/history/part1", "about/history/part2"]

auto_hash = Hash.new{ |h,k| h[k] = Hash.new &h.default_proc }

array.each{ |path|
  sub = auto_hash
  path.split( "/" ).each{ |dir| sub[dir]; sub = sub[dir] }
}
+1  A: 
require 'rubygems'
require 'builder'

paths = ["home", "about", "about/history", "about/company", "about/history/part1", "about/history/part2"]

auto_hash = Hash.new{ |h,k| h[k] = Hash.new &h.default_proc }

paths.each do |path|
  sub = auto_hash
  path.split( "/" ).each{ |dir| sub[dir]; sub = sub[dir] }
end

def build_branch(branch, xml)
  directories = branch.keys.reject{|k| branch[k].empty? }.sort
  leaves = branch.keys.select{|k| branch[k].empty? }.sort

  directories.each do |directory|
    xml.li(directory, :class => 'folder')
    xml.ul do
      build_branch(branch[directory], xml)
    end
  end

  leaves.each do |leaf|
    xml.li(leaf, :class => 'leaf')
  end
end

xml = Builder::XmlMarkup.new(:indent => 2)

xml.ul do
  build_branch(auto_hash, xml)
end

puts xml.target!
fowlduck
MONEY! Thanks :)
Jose Fernandez