ruby如何生成树结构表单数组?
我有一个数组,其中包含如下项目列表ruby如何生成树结构表单数组?,ruby,arrays,performance,algorithm,tree,Ruby,Arrays,Performance,Algorithm,Tree,我有一个数组,其中包含如下项目列表 arr = [ {:id=>1, :title=>"A", :parent_id=>nil}, {:id=>2, :title=>"B", :parent_id=>nil}, {:id=>3, :title=>"A1", :parent_id=>1}, {:id=>4, :title=>"A2", :parent_id=>1}
arr = [
{:id=>1, :title=>"A", :parent_id=>nil},
{:id=>2, :title=>"B", :parent_id=>nil},
{:id=>3, :title=>"A1", :parent_id=>1},
{:id=>4, :title=>"A2", :parent_id=>1},
{:id=>5, :title=>"A11", :parent_id=>3},
{:id=>6, :title=>"12", :parent_id=>3},
{:id=>7, :title=>"A2=121", :parent_id=>6},
{:id=>8, :title=>"A21", :parent_id=>4},
{:id=>9, :title=>"B11", :parent_id=>2},
{:id=>10, :title=>"B12", :parent_id=>2},
...
]
如果parent\u id
是nil
则其应为父节点,如果parent\u id
不是nil
则其应位于特定父节点下
基于id
和parent\u id
,我想提供如下响应:
-A
-A1
-A11
-A12
-A123
-A2
-A21
-B
-B1
-B11
-B12
如何生成上面提到的响应
谢谢您可以使用宝石,如:
hash_tree
提供了一种将子树呈现为有序结构的方法
嵌套哈希:
Tag.hash_tree
#=> {a => {b => {c1 => {d1 => {}}, c2 => {d2 => {}}}, b2 => {}}}
或:
祖先可以将整个子树排列成嵌套的散列,以便
从数据库检索后的导航<代码>树节点。排列可以
例如返回:
{ #<TreeNode id: 100018, name: "Stinky", ancestry: nil>
=> { #<TreeNode id: 100019, name: "Crunchy", ancestry: "100018">
=> { #<TreeNode id: 100020, name: "Squeeky", ancestry: "100018/100019">
=> {}
}
}
}
并非要取代经验证的宝石,但根据您的需要,您可以使用以下简单的产品:
groups = arr.group_by{ |x| x[:parent_id] }
groups.default = []
build_tree =
lambda do |parent|
[parent[:title], groups[parent[:id]].map(&build_tree)]
# or
# { parent[:title] => groups[parent[:id]].map(&build_tree) }
end
p build_tree[:id => nil][1] # :id => nil is not required, empty hash will work too
# => [["A", [["A1", [["A11", []], ["A12", [["A122", []]]]]], ["A2", [["A21", []]]]]], ["B", [["B11", []], ["B12", []]]]]
一个例子:
#!/usr/bin/env ruby
root = {:id => 0, :title => '', :parent_id => nil}
arr = arr = [
{:id=>1, :title=>"A", :parent_id=>nil},
{:id=>2, :title=>"B", :parent_id=>nil},
{:id=>3, :title=>"A1", :parent_id=>1},
{:id=>4, :title=>"A2", :parent_id=>1},
{:id=>5, :title=>"A11", :parent_id=>3},
{:id=>6, :title=>"12", :parent_id=>3},
{:id=>7, :title=>"A2=121", :parent_id=>6},
{:id=>8, :title=>"A21", :parent_id=>4},
{:id=>9, :title=>"B11", :parent_id=>2},
{:id=>10, :title=>"B12", :parent_id=>2},
]
map = {}
arr.each do |e|
map[e[:id]] = e
end
@@tree = {}
arr.each do |e|
pid = e[:parent_id]
if pid == nil || !map.has_key?(pid)
(@@tree[root] ||= []) << e
else
(@@tree[map[pid]] ||= []) << e
end
end
def print_tree(item, level)
items = @@tree[item]
unless items == nil
indent = level > 0 ? sprintf("%#{level * 2}s", " ") : ""
items.each do |e|
puts "#{indent}-#{e[:title]}"
print_tree(e, level + 1)
end
end
end
print_tree(root, 0)
这是Rails项目吗?是的,它是Rails 3.0.3项目。您可以使用类似gem的项目,或者两者都可以生成嵌套哈希。感谢支持,是否可以生成它而不在数据库中添加任何字段?闭包树使用
parent\u id
列,您只需设置一个附加表并运行rake任务,看到这两个gem真的很棒,我们能在没有任何数据库迁移的情况下完成吗?谢谢你的时间,对我来说理解build_tree背后的概念很复杂。
groups = arr.group_by{ |x| x[:parent_id] }
groups.default = []
build_tree =
lambda do |parent|
[parent[:title], groups[parent[:id]].map(&build_tree)]
# or
# { parent[:title] => groups[parent[:id]].map(&build_tree) }
end
p build_tree[:id => nil][1] # :id => nil is not required, empty hash will work too
# => [["A", [["A1", [["A11", []], ["A12", [["A122", []]]]]], ["A2", [["A21", []]]]]], ["B", [["B11", []], ["B12", []]]]]
#!/usr/bin/env ruby
root = {:id => 0, :title => '', :parent_id => nil}
arr = arr = [
{:id=>1, :title=>"A", :parent_id=>nil},
{:id=>2, :title=>"B", :parent_id=>nil},
{:id=>3, :title=>"A1", :parent_id=>1},
{:id=>4, :title=>"A2", :parent_id=>1},
{:id=>5, :title=>"A11", :parent_id=>3},
{:id=>6, :title=>"12", :parent_id=>3},
{:id=>7, :title=>"A2=121", :parent_id=>6},
{:id=>8, :title=>"A21", :parent_id=>4},
{:id=>9, :title=>"B11", :parent_id=>2},
{:id=>10, :title=>"B12", :parent_id=>2},
]
map = {}
arr.each do |e|
map[e[:id]] = e
end
@@tree = {}
arr.each do |e|
pid = e[:parent_id]
if pid == nil || !map.has_key?(pid)
(@@tree[root] ||= []) << e
else
(@@tree[map[pid]] ||= []) << e
end
end
def print_tree(item, level)
items = @@tree[item]
unless items == nil
indent = level > 0 ? sprintf("%#{level * 2}s", " ") : ""
items.each do |e|
puts "#{indent}-#{e[:title]}"
print_tree(e, level + 1)
end
end
end
print_tree(root, 0)
-A
-A1
-A11
-12
-A2=121
-A2
-A21
-B
-B11
-B12