我有:
blockchain = [
{ from_user: nil, to_user: "brian", amount: 21000 },
{ from_user: "brian", to_user: "ben", amount: 9000 },
{ from_user: "brian", to_user: "jeff", amount: 7000 },
{ from_user: "ben", to_user: "jeff", amount: 400 },
{ from_user: "brian", to_user: "jeff", amount: 1500 },
{ from_user: "jeff", to_user: "brian", amount: 4500 },
{ from_user: "jeff", to_user: "ben", amount: 1750 }
]
我想获得每个人的最终金额,总计,但剩余硬币。它应该打印出来:
Brian's balance is 8000
Ben's balance is 10350
Jeff's balance is 2650
我试图弄清楚如何编写代码。有人可以帮忙吗?
答案 0 :(得分:1)
步骤1:创建一个默认值为零的空散列
此哈希的键将是用户,其值将是每个用户在任何给定时间所拥有的数量。
让哈希h
的默认值为0
意味着如果h[k]
没有密钥{{1},0
返回h
}。在这里,我们将编写k
,它扩展为
h[k] += 1
如果(在执行此表达式之前)h[k] = h[k] + 1
没有右侧的键h
k
返回零,那么我们有
h[k]
此后,右侧的h[k] = 0 + 1
#=> 1
将为正整数。
如果您想知道为什么表达式左侧的h[k]
不返回h[k]
,请记住0
是实际表达式的语法糖
h[k] = h[k] + 1
我们在左侧有方法h.[]=(h.[](k) + 1)
,在右侧有方法[]=
。当[]
没有密钥h.[](k)
时,是h
返回默认值。
找到一种Hash方法k
(实际上不是“ m”)来做到这一点。
m
问号意味着您必须为方法h = Hash.m(?)
提供一个参数。
步骤2:逐步浏览m
中的哈希值以更新哈希值blockchain
h
我们现在拥有打印所需结果所需的信息。
在实践中,我们将使用方法Enumerable#each_with_object链接这两个步骤:
blockchain.each do |g|
h[?] += ?
h[?] -= ? unless ? == nil
end
h #=> {"brian"=>8000, "ben"=>10350, "jeff"=>2650}
此处blockchain.each_with_object(Hash.m(?)) do |g,h|
h[?] += ??
h[?] -= ?? unless ?? == nil
end
#=> {"brian"=>8000, "ben"=>10350, "jeff"=>2650}
和?
分别是参数和表达式的占位符。
答案 1 :(得分:1)
您可以通过以下方式进行操作:
blockchain = [
{ from_user: nil, to_user: "brian", amount: 21000 },
{ from_user: "brian", to_user: "ben", amount: 9000 },
{ from_user: "brian", to_user: "jeff", amount: 7000 },
{ from_user: "ben", to_user: "jeff", amount: 400 },
{ from_user: "brian", to_user: "jeff", amount: 1500 },
{ from_user: "jeff", to_user: "brian", amount: 4500 },
{ from_user: "jeff", to_user: "ben", amount: 1750 }
]
users = {}
blockchain.each do |block|
users[block[:from_user]] = 0 if !users.keys.include?(block[:from_user]) && block[:from_user].present?
users[block[:to_user]] = 0 if !users.keys.include?(block[:to_user])
users[block[:to_user]] = users[block[:to_user]] + block[:amount]
users[block[:from_user]] = users[block[:from_user]] - block[:amount] if block[:from_user].present?
end
puts users
users
哈希将包含您所需的输出
{"brian"=>8000, "ben"=>10350, "jeff"=>2650}
答案 2 :(得分:1)
下面是简单实施,以实现每个人的平衡,
add = blockchain.group_by { |x| x[:to_user] }.reject { |k,v| k.nil? }.transform_values { |v| v.map { |x| x[:amount] }.sum }
# => {"brian"=>25500, "ben"=>10750, "jeff"=>8900}
sub = blockchain.group_by { |x| x[:from_user] }.reject { |k,v| k.nil? }.transform_values { |v| v.map { |x| x[:amount] }.sum }
# => {"brian"=>17500, "ben"=>400, "jeff"=>6250}
people = (add.keys + sub.keys).uniq
# => ["brian", "ben", "jeff"]
people.each { |x| puts "#{x.capitalize}'s balance is #{add[x].to_i - sub[x].to_i}" }
# Brian's balance is 8000
# Ben's balance is 10350
# Jeff's balance is 2650
# => ["brian", "ben", "jeff"]
答案 3 :(得分:0)
Amogh Hegde的出色回答,但不知何故,它在我的系统上不支持ruby 2.5.1,但是如果您在顶部脚本中添加require 'active_support/all'
,它将起作用。但是我尝试不添加任何东西。因此做了很小的改动。以下是我是否更改了:from_user
条件的情况下刚刚更改的完整代码,因此我已转换为字符串,然后使用空方法进行了检查。
blockchain = [
{ from_user: nil, to_user: "brian", amount: 21000 },
{ from_user: "brian", to_user: "ben", amount: 9000 },
{ from_user: "brian", to_user: "jeff", amount: 7000 },
{ from_user: "ben", to_user: "jeff", amount: 400 },
{ from_user: "brian", to_user: "jeff", amount: 1500 },
{ from_user: "jeff", to_user: "brian", amount: 4500 },
{ from_user: "jeff", to_user: "ben", amount: 1750 }
]
users = {}
blockchain.each do |block|
users[block[:from_user]] = 0 if !users.keys.include?(block[:from_user]) && !block[:from_user].to_s.empty?
users[block[:to_user]] = 0 if !users.keys.include?(block[:to_user])
users[block[:to_user]] = users[block[:to_user]] + block[:amount]
users[block[:from_user]] = (users[block[:from_user]] - block[:amount]) if !block[:from_user].to_s.empty?
end
puts users
我得到以下回应。
{"brian"=>8000, "ben"=>10350, "jeff"=>2650}
答案 4 :(得分:0)
一次迭代:
blockchain.each_with_object(Hash.new(0)) do |h, nh|
nh[h[:from_user]] -= h[:amount]
nh[h[:to_user]] += h[:amount]
end
#=> {nil=>-21000, "brian"=>8000, "ben"=>10350, "jeff"=>2650}
blockchain.each_with_object(Hash.new { |h,k| h[k] = Hash.new(0) }) do |h, nh|
nh[h[:from_user]][:out] -= h[:amount]
nh[h[:to_user]][:in] += h[:amount]
end
#=> {nil=>{:out=>-21000}, "brian"=>{:in=>25500, :out=>-17500}, "ben"=>{:in=>10750, :out=>-400}, "jeff"=>{:in=>8900, :out=>-6250}}
Enumerable#group_by
和Hash#transform_values
计算收入和结果,然后合并在一起。
收入是:
incomes = blockchain.group_by { |k,v| k[:to_user] }.transform_values{ |a| a.sum { |h| h[:amount] }}
#=> {"brian"=>25500, "ben"=>10750, "jeff"=>8900}
结果为(负):
outcomes = blockchain.group_by { |k,v| k[:from_user] }.transform_values{ |a| -a.sum { |h| h[:amount]}}
#=> {nil=>-21000, "brian"=>-17500, "ben"=>-400, "jeff"=>-6250}
然后合并,使用Hash#merge
传递一个块:
incomes.merge(outcomes) { |k, income, outcome| income + outcome }
#=> {"brian"=>8000, "ben"=>10350, "jeff"=>2650, nil=>-21000}