Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ruby如何生成树结构表单数组?_Ruby_Arrays_Performance_Algorithm_Tree - Fatal编程技术网

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