ruby-on-rails - ruby 中的树结构与父子数组格式没有 gem ?

标签 ruby-on-rails ruby arrays

我有一个数组,其中包含这样的项目列表

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_id 为 nil 那么它应该是父节点,如果 parent_id 不为 nil 那么它应该在特定的父节点下。

基于 id 和 parent_id,我想提供这样的响应:

-A
  -A1
    -A11
    -A12
      -A123
  -A2
    -A21
-B
  -B1
    -B11
    -B12

我如何生成上述响应?

最佳答案

这比您想象的要容易,您只需要了解几件简单的事情:

  1. nil 是一个完全有效的哈希键。
  2. 您可以使用 nil 作为树的虚拟根,以便所有 :parent_id 都指向树中的对象。
  3. 您可以同时通过两种方式遍历数组和跟踪条目:通过 :id 和通过 :parent_id

首先是一个哈希表示的树:

tree = Hash.new { |h,k| h[k] = { :title => nil, :children => [ ] } }

我们将从根到叶,因此我们只对父/子关系的子端感兴趣,因此 :children 数组的默认值。

然后是一个简单的迭代,填充 :title:children:

arr.each do |n|
  id, parent_id = n.values_at(:id, :parent_id)
  tree[id][:title] = n[:title]
  tree[parent_id][:children].push(tree[id])
end

请注意,节点(包括父节点)在第一次出现时由 treedefault_proc 自动创建,因此 中的节点顺序arr 是无关紧要的。

这给我们留下了 tree 中的树,其中键是 :id(包括 nil 键处的虚拟根)和这些值是从该点开始的子树。

然后如果你查看 tree[nil][:children] 剥离虚拟根,你会看到这个:

[
  { :title => "A", :children => [
    { :title => "A1", :children => [
      { :title => "A11", :children => [] },
      { :title => "12", :children => [
        { :title => "A2=121", :children => [] }  
      ] }
    ] },
    { :title => "A2", :children => [
      { :title => "A21", :children => [] }   
    ] }
  ] },
  { :title => "B", :children => [
    { :title => "B11", :children => [] },
    { :title => "B12", :children => [] }
  ] }
]

这正是您正在寻找的结构,您应该能够从那里获取它。这与您的示例响应不匹配,但那是因为您的示例 arr 也不匹配。

你也可以说:

tree = arr.each_with_object(Hash.new { |h,k| h[k] = { :title => nil, :children => [ ] } }) do |n, tree|
  #...
end

如果您更喜欢嘈杂的第一行而不是单独的 tree 声明。

关于ruby-on-rails - ruby 中的树结构与父子数组格式没有 gem ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21494633/

相关文章:

ruby-on-rails - 如何使用monit监控nginx乘客

ruby-on-rails - 将 CSS 样式添加到 Rails 3 中的 form_tag

java - 将数组的名称设置为 String 变量的值

c - malloc 总是分配相同的地址

javascript - 使用 Ruby 代码解析 Javascript

ios - Swift 中合并子数组

ruby-on-rails - 开发中的 Rails.cache.fetch 缓存

ruby-on-rails - 在 Controller (RAILS) 中动态创建方法

ruby-on-rails - window : rails: error installing bson_ext

ruby-on-rails - 未定义方法 `[]' 为 true :TrueClass