树struture红宝石与无宝石数组形式父子? [英] tree struture in ruby with parent child in array format without gems?

查看:91
本文介绍了树struture红宝石与无宝石数组形式父子?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数组,它有这样的项目列表

I have a array which have list of item like this

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是零那么它应该是父节点,如果PARENT_ID不是nil那么它应该来自特定父之下。

If parent_id is nil then its should be the parent node, if parent_id is not nil then it should comes under the particular parent.

,我想提供这样的回应:

Based on id and parent_id, I want to provide a response like this:

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

我怎么会产生上面提到的做出响应?

How could I generate a responds mentioned above?

推荐答案

这是比你想象的,你只需要实现几个简单的事情变得更加容易:

This is easier than you think, you just need to realize a couple simple things:


  1. 是一个完全有效的哈希键。

  2. 您可以使用作为虚拟根你的树,使所有的:PARENT_ID ■在事点在你的树。

  3. 您可以通过两种方式阵列和跟踪条目一次迭代:由:ID :PARENT_ID

  1. nil is a perfectly valid Hash key.
  2. You can use nil as a virtual root for your tree so that all the :parent_ids point at things in your tree.
  3. You can iterate through the array and track entries in two ways at once: by :id and by :parent_id.

首先一棵树再$ P $由哈希psented:

First a tree represented by a Hash:

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

我们打算从根去叶所以我们只能在父/子关系的孩子一边感兴趣,因此:儿童阵列中的缺省值。

We're going to be going from the root to the leaves so we're only interested in the children side of the parent/child relationship, hence the :children array in the default values.

然后进行简单的迭代,在填写:标题:儿童自有其道理:

Then a simple iteration that fills in the :titles and :children as it goes:

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

请注意,该节点(包括父节点)自动 default_proc 第一次创建他们见过那么在的节点顺序改编是无关紧要的。

Note that the nodes (including the parent nodes) are automatically created by tree's default_proc the first time they're seen so the node order in arr is irrelevant.

这是留给我们的树,其中键是:ID S(包括虚拟根在在键)和值是从该点的子树。

That leaves us with the tree in tree where the keys are :ids (including the virtual root at the nil key) and the values are subtrees from that point.

这时如果你看看树[无] [:儿童] 剥离虚拟根目录,你会看到这一点:

Then if you look at tree[nil][:children] to peel off the virtual root, you'll see this:

[
  { :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 => [] }
  ] }
]

和刚好有你要找的结构,你应该能够把它从那里。这不符合您的样本响应但那是因为您的样本改编也不行。

and that has exactly the structure you're looking for and you should be able to take it from there. That doesn't match your sample response but that's because your sample arr doesn't either.

您也可以说:

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

如果您preferred,与其嘈杂的第一行到一个单独的声明。

if you preferred that rather noisy first line to a separate tree declaration.

这篇关于树struture红宝石与无宝石数组形式父子?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆