红宝石中的2级深度分组

时间:2011-02-11 13:37:56

标签: ruby-on-rails ruby

所以我有一系列记录,我想按2级分组

基本上我想group_by{|x| x.field1 }然后将hash中的每个值进一步按field2分组。有效地导致我可以倾倒的树。

def treemaker(array = [])
  tree = ledgers.group_by{|x|x.master_group}
  tree.each{|x,z| tree[x] = z.group_by{|y| y.account_group}}
  tree
end

然后我会以一种可以放入&#34树的方式渲染树。 javascript插件。

有更有效的方法吗?

示例输入:模型包含的ActiveRecord对象数组,字段master_group,account_group和name

Class MyModel < ActiveRecord::Base
  validates :master_group, :account_group, :name, :presence => true
end

示例输出:

{"master_group1" => {"account_group1" => ["name1","name2",...], 
                     "account_groupx" => ["name3", "name4",...],
                     ....}, 
 "master_group2" => {"account_group2" => ["namex", "namey"]},
 ...
}

我并不是专门寻找&#34; SQL分组&#34;解决方案(但那也很好)。只是在任何给定的ruby对象列表上使用枚举的解决方案。

2 个答案:

答案 0 :(得分:3)

@xaxxon基本上用“默认值哈希”路径让我以正确的方式思考。

我想我现在可以在我的模型中添加一个方法,我可以在最后使用各种范围并在树上添加树,以使我的模型处于树模式。

class MyModel < ActiveRecord::Base

  validates :master_group, :account_group, :name, :presence => true
  def self.tree(field1 = 'master_group', field2 = 'account_group')
    tree = Hash.new{|hash,key| hash[key] = Hash.new{|h,k| h[k] = []}}
    all.each do |item|
      tree[item.send('field1')][item.send('field2')].push(item)
    end
    tree # bob's your uncle!
  end

end

MyModel.recent.tree => Hash of Hash of arrays

答案 1 :(得分:1)

设置一些假数据

  

富= [{:A =大于1,:B =大于2},{:A =→3,:B =→4}]

设置输出数据结构

  

树= {}

填充输出数据结构 - 这看起来很奇怪,因为你必须填充不存在时不存在的哈希值,因此需要填充|| = {}。

  

foo.each {|事| (树[事情[:A]] || = {})[事情[:B]] =事情}

看起来不错......:a是您的主要群组,并且:b是您的account_group

  

pp tree

     

{1 =&gt; {2 =&gt; {:a =&gt; 1,:b =&gt; 2}},3 =&gt; {4 =&gt; {:a =&gt; 3,:b = →4}}}