我有以下枚举器
[
#<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)。如果有多行,那么应该为每个用户执行所有行的聚合。
答案 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")