rails:对象数组,如何对对象属性的值求和?

时间:2013-09-11 10:30:23

标签: ruby-on-rails arrays hash sum

我有一些从一些查询获得的对象数组,所有对象都有属性:id,title和quantity。 问题是:如何通过id对数量求和并保存每个字段? 我试过这个片段

h=Hash.new(0)
a.each do |el|
  h[el.id] += el.quantity
end

这就是,但我失去了头衔!我怎样才能在哈希中找到标​​题?

谢谢!

更新解决方案

我认为数组的数据可能有数千条记录,所以我决定预测汇总数量。 感谢一个解决方案的例子,现在每次从主表中获取记录块时,我都会用这种方式详细说明数据

@agg = Hash.new(Array.new)
master.scope.each do |mst|
  recs = mst.select.........
  recs.each do |el|
      store = @agg[el.id].empty? ? 0 : @agg[el.id][1]
      @agg[el.id] = [el.title, el.quantity+store]
  end
end   

最后,@ agg保存所有且仅包含聚合数据。

如果有人可以提出更一般或更优雅的解决方案。

感谢所有人。

乔治

3 个答案:

答案 0 :(得分:1)

哈希元素中有2个值,键和值,值;因此h [key] = value。

为了您的目标,您可以将值设为数组/哈希,其中第一个元素是标题,第二个元素是数量。

然而你正在做的事情并非总结/积累任何东西。你只是在元素中构建一个哈希。每次迭代时,为该特定id创建h [id] = h [quantity]。你只是将你的el对象变成了哈希。如果要累积值,请执行此操作。

sum = 0
h = Hash.new(Array.new) 
a.each do |el|
  sum += el.quantity
  h[el.id] = [el.title, sum]
end

如果您最终想要的只是最终按照ID的顺序累积数量,请尝试:

prior = nil
a.each do |el|
  el.quantity += prior.quantity unless prior.nil?
  prior = el
end

答案 1 :(得分:0)

哈希是键值对的集合,因此您无法在单个哈希元素中存储ID,数量和标题。你想要的是一个以id或title作为键的哈希,以及一个标题或id和数量作为值的嵌套哈希。 类似的东西:

h = Hash.new { |hash, key| hash[key] = {} }
a.each do |el|
  if h[el.id][el.title].nil?
    h[el.id][el.title] = el.quantity
  else 
    h[el.id][el.title] += el.quantity
  end
end

答案 2 :(得分:0)

如果标题对于id是唯一的,则可以执行此操作,

h=Hash.new
a.each do |el|
  h[el.id] ||= {:title => el.title, :quantity => 0}
  h[el.id][:quantity] += el.quantity
end

请注意,这将保留它遇到id的第一个title值。

如果可以在db查询中执行此操作,可能会更快。像Sthing一样

recs = mst.select("SUM(quantity) as total_quantity, id, title").group(:id)

这将返回按唯一id分组的记录,并且每个组的quantity汇总并以rec.total_quantity形式提供。