Ruby枚举器中的金额总和

时间:2014-02-26 22:24:46

标签: ruby-on-rails ruby ruby-on-rails-3

我有以下枚举器

[
 #<User number: "23", amt: 1.0, amt1: 0.1>, 
 #<User number: "23", amt: 2.0, amt1: 0.1>, 
 #<User number: "24", amt: 3.0, amt1: 0.3>, 
 #<User number: "25", amt: 3.3, amt1: 0.4>
]

我在做

users.each { |user| user.select { |a| a.inject(0){|sum, i| sum + ( amt - amt1) } }}

我收到错误(枚举器的未定义方法注入)。上面的语法有什么问题?

我需要为每个用户计算(amt - amt1)。如果有多行,那么应该为每个用户执行所有行的聚合。

4 个答案:

答案 0 :(得分:2)

功能性解决方案(没有任何额外的可变变量)只使用.group_by.reduce

users.group_by do |user| 
  user.number
end.map do |key, value| 
  User.new(number: key, 
           amt: value.reduce(0) { |acc, s| acc + (s.amt - s.amt1) })
end

昨天与this question I answered非常相似。检查一下,详细查看一个包含对象数组的工作示例。

答案 1 :(得分:1)

users = [
 #<User number: "23", amt: 1.0, amt1: 0.1>, 
 #<User number: "23", amt: 2.0, amt1: 0.1>, 
 #<User number: "24", amt: 3.0, amt1: 0.3>, 
 #<User number: "25", amt: 3.3, amt1: 0.4>
]

sum = {}
grouped_users = users.group_by{|user| user.number}
grouped_users.map{|number, users| sum[number] = users.sum{|u| u.amt - u.amt1}}
p sum

答案 2 :(得分:1)

设置部分

users = [
{number: "23", amt: 1.0, amt1: 0.1},
{number: "23", amt: 2.0, amt1: 0.1},
{number: "24", amt: 3.0, amt1: 0.3},
{number: "25", amt: 3.3, amt1: 0.4}
]
users.map! { |user| OpenStruct.new user }

以下是真实的东西,上面只是为了创造类似OP用户的东西

 Hash[users.group_by(&:number).map { |n, g| [n, g.inject(0) { |sum, user| sum += (user.amt - user.amt1) } ] } ]
#=> {"23"=>2.8, "24"=>2.7, "25"=>2.9}

OR

users.each_with_object(Hash.new(0)) { |u, h| h[u.number] += (u.amt - u.amt1) }
#=> {"23"=>2.8, "24"=>2.7, "25"=>2.9}

答案 3 :(得分:1)

我的纯Ruby会接受它:

sum = users.group_by(&:number).each.with_object(Hash.new{0}) do |(n, users), sum|
  sum[n] += users.map { |u| u.amt - u.amt1 }.inject(:+)
end

我将如何在Rails中执行此操作:

User.group("number").sum("amt - amt1")