我有一个ActiveRecord关系,看起来像这样:
[
{
timestamp: Tue, 02 Oct 2018 00:00:00 PDT -07:00,
user_id: 3,
organization_id: 1,
all_sales: 10,
direct_sales: 7,
referred_sales: 3,
},
{
timestamp: Wed, 03 Oct 2018 00:00:00 PDT -07:00,
user_id: 3,
organization_id: 1,
all_sales: 17,
direct_sales: 8,
referred_sales: 9,
},
{
timestamp: Thu, 04 Oct 2018 00:00:00 PDT -07:00,
user_id: 3,
all_sales: 3,
direct_sales: 3,
referred_sales: 0,
}
]
Run Code Online (Sandbox Code Playgroud)
我想做的是创建一个与销售相关的所有关键字的"总和"(为了我们的目的,我不需要timestamp,user_id或者organization_id,基本上,我想以这样的结尾:
{
all_sales: 30
direct_sales: 18
referred_sales: 12
}
Run Code Online (Sandbox Code Playgroud)
有这种优雅的ruby-ish方式吗?我可以轻松地为每个销售类别创建一组变量,并在迭代原始关系时对其进行扩充,但我想看看社区是否有更清晰的方法.实际上,这些哈希中的每一个都有超过3个相关键,因此我担心这种方法会很快变得混乱.
编辑:我也在SO上检查了类似问题的其他一些答案(例如:更好地在散列数组中对值进行求和),但理想情况下我不会迭代这么多次.
这将起作用:
arr.each_with_object({}) do |obj, hash|
%i[all_sales direct_sales referred_sales].each do |sym|
hash[sym] = hash[sym].to_i + obj[sym]
end
end
Run Code Online (Sandbox Code Playgroud)
这是一次迭代,您可以将嵌套循环编写为 3 行不同的行,但在我看来,这种方式更简洁一些。
注意:to_i在获取先前值的同时调用hash[sym]它最初是niland nil.to_i == 0。或者,您可以将所有未知计数初始化为 0,如下所示:
arr.each_with_object(Hash.new(0)) do |obj, hash|
%i[all_sales direct_sales referred_sales].each do |sym|
hash[sym] += obj[sym]
end
end
Run Code Online (Sandbox Code Playgroud)
由于您是从ActiveRecord Relation开始的,因此您可以使用pluck来计算SQL的所有总和,并让它返回一个包含总数的数组:
SalesModel.pluck('SUM(all_sales)', 'SUM(direct_sales)', 'SUM(referred_sales)')
#=> [30, 18, 12]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
276 次 |
| 最近记录: |