0

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

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

就这样,但我失去了头衔!如何在哈希 h 中包含标题?

谢谢!

更新解决方案

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

@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 保存所有且仅聚合的数据。

如果有人可以提供更通用或更优雅的解决方案,请挺身而出。

谢谢大家。

乔治奥

4

3 回答 3

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
于 2013-09-11T11:01:20.137 回答
0

散列是键、值对的集合,因此您不能将 id、数量和标题存储在单个散列元素中。你想要的是一个以 id 或 title 作为键的散列和一个以 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
于 2013-09-11T10:52:23.330 回答
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。

如果您可以在 db 查询中执行此操作,它可能会更快。类似的东西

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

这将返回按唯一分组的记录,id并将quantity每个组的 求和并作为rec.total_quantity.

于 2013-09-11T10:53:42.053 回答