从活动记录中散列

时间:2019-07-09 13:10:12

标签: ruby-on-rails ruby activerecord hash

可能有相似的名称和日期。但是,取相似日期的总和。

   #<ActiveRecord::Relation [Model name: "a", date: "20190703", count: 20>
   #<ActiveRecord::Relation [Model name: "b", date: "20190702", count: 10>
   #<ActiveRecord::Relation [Model name: "a", date: "20190702", count: nil>
   #<ActiveRecord::Relation [Model name: "c", date: "20190703", count: 20>
   #<ActiveRecord::Relation [Model name: "c", date: "20190702", count: 3>
   #<ActiveRecord::Relation [Model name: "c", date: "20190702", count: 5> ...etc

预期结果将是

{
    :name=>"a", :data=>[{:date=>20190702, :count=>10}, {:date=>20190703, :count=>20}.....]
    :name=>"b", :data=>[{:date=>20190702, :count=>10}, ...etc]
    :name=>"c", :data=>[{:date=>20190702, :count=>8}, {:date=>20190703, :count=>20}, ..etc]
}

2 个答案:

答案 0 :(得分:1)

您可以拥有

hash = users.group_by { |x| x.name }

hash.map do |name, model_data|
  {  
     name: name,
     data: model_data.group_by { |x| x[:date] }.values.map { |z| {date: z[0][:date], count: (z.inject(0) { |m,a| m += a[:count].to_i })} }
  }
end

输出将是

[
    {:name=>"a", :data=>[{:date=>20190702, :count=>10}, {:date=>20190703, :count=>20}.....]},
    {:name=>"b", :data=>[{:date=>20190702, :count=>10}, ...etc]},
    {:name=>"c", :data=>[{:date=>20190702, :count=>8}, {:date=>20190703, :count=>20}, ..etc]}
]

答案 1 :(得分:1)

因此,考虑到这是ActiveRecord数据,为什么不使用

data = Model.group(:name,:date).order(name: :asc, date: :asc).sum(:count)
data.each_with_object(Hash.new {|h,k| h[k] = []}) do |((name,date),count),obj|
  obj[name] << {date: date, count: count} 
end

这将产生:

{
  "a"=>[{:date=>20190702, :count=>0}, {:date=>20190703, :count=>20}],
  "b"=>[{:date=>20190702, :count=>10}],
  "c"=>[{:date=>20190702, :count=>8}, {:date=>20190703, :count=>20}]
}

并且所有的求和和分组都放在事物的SQL端(聚合时非常有效)