工作中用到把表里的树显示到页面上,写了一个小程序来验证,不知大家会不会用到。
records = [{
:name => '01',
:id => 1
},{
:name => '0101',
:id => 2
},{
:name => '010101',
:id => 3
},{
:name => '010102',
:id => 4
},{
:name => '010103',
:id => 5
},{
:name => '02',
:id => 6
},{
:name => '0201',
:id => 7
},{
:name => '0202',
:id => 8
},{
:name => '020201',
:id => 9
},{
:name => '020202',
:id => 10
},{
:name => '0203',
:id => 11
},{
:name => '03',
:id => 12
},{
:name => '04',
:id => 13
},{
:name => '0401',
:id => 14
},{
:name => '040101',
:id => 15
},{
:name => '04010101',
:id => 16
}]
class TreeNode
attr_accessor :name, :id, :children
def initialize(r)
@name = r[:name]
@id = r[:id]
end
def length
@name.length
end
def push_child(node)
@children ||= []
@children.push node
end
def to_hash
result = {name: @name, id: @id}
@children.nil? ? result : result.merge!(children: @children.collect(&:to_hash))
end
end
stack = [TreeNode.new({:name => ''})]
is_debug = false
records.each do |r|
node = TreeNode.new(r)
puts "#{node.id}: #{node.name}\n" if is_debug
stack.pop while stack.last.length >= node.length
stack.last.push_child node
stack.push node
puts "#{stack.collect(&:to_hash)}\n" if is_debug
end
stack.first.children.collect(&:to_hash)
=> [{:name=>"01", :id=>1, :children=>[{:name=>"0101", :id=>2, :children=>[{:name=>"010101", :id=>3}, {:name=>"010102", :id=>4}, {:name=>"010103", :id=>5}]}]}, {:name=>"02", :id=>6, :children=>[{:name=>"0201", :id=>7}, {:name=>"0202", :id=>8, :children=>[{:name=>"020201", :id=>9}, {:name=>"020202", :id=>10}]}, {:name=>"0203", :id=>11}]}, {:name=>"03", :id=>12}, {:name=>"04", :id=>13, :children=>[{:name=>"0401", :id=>14, :children=>[{:name=>"040101", :id=>15, :children=>[{:name=>"04010101", :id=>16}]}]}]}]