我想计算我的统计数据的增量。我已经尝试过HashDiff gem来比较哈希值。
a = {"Lima, Peru"=>"83", "Chicago, IL"=>"35"}
b = {"Lima, Peru"=>"80", "Chicago, IL"=>"40", "Krakow, Poland" => '3'}
CalculateDelta.new(A,B).execute
b = {"Lima, Peru"=>"-3", "Chicago, IL"=>"5", "Krakow, Poland" => '3'}
甚至更好
b = {"Lima, Peru"=>["-", "3"], "Chicago, IL"=>["+", "5"], "Krakow, Poland" => ["+", '3']}
我已经写过这样的东西了
class CalculateDeltas < Struct.new(:a, :b)
def calculate
aa = a.to_a
ba = b.to_a
c = aa + ba
c.group_by(&:first).map{|k,v| [k, v.map(&:last).inject(:+)]}
end
end
答案 0 :(得分:2)
这样的东西?:
class CalculateDelta
attr_reader :source, :target
def initialize(source, target)
@source = source
@target = target
end
def execute
target.each_with_object({}) do |(k, v), result|
result[k] = if source[k]
source_value, v = source[k].to_i, v.to_i
source_value > v ? ['-', "#{source_value - v}"]: ['+', "#{v - source_value}"]
else
['+', v]
end
end
end
end
a = {"Lima, Peru"=>"83", "Chicago, IL"=>"35"}
b = {"Lima, Peru"=>"80", "Chicago, IL"=>"40", "Krakow, Poland" => '3'}
puts CalculateDelta.new(a,b).execute
#=> {"Lima, Peru"=>["-", "3"], "Chicago, IL"=>["+", "5"], "Krakow, Poland"=>["+", "3"]}
答案 1 :(得分:1)
保持简单:
b.keys.each { |k| b[k] = (b[k].to_i-a[k].to_i).to_s if a.key?(k) }
b #=> {"Lima, Peru"=>"-3", "Chicago, IL"=>"5", "Krakow, Poland" => "3"}
请注意,规范是变异b
。
可以进一步简化,但我不建议:
b.keys.each { |k| b[k] = (b[k].to_i-a[k].to_i).to_s }
b
如果a[k] = nil
没有密钥a
,我听到有人反对k
。这是真的,但nil.to_i => 0
。 : - )
答案 2 :(得分:0)
Hash.new().tap{|h| b.each{|k,v| h[k] = v.to_i}; a.each{|k,v| h[k] -= v.to_i}}
返回{"Lima, Peru"=>-3, "Chicago, IL"=>5, "Krakow, Poland"=>3}
修改强> 要使此代码仅返回散列使用中的字符串:
Hash.new().tap{|h| b.each{|k,v| h[k] = v.to_i}; a.each{|k,v| h[k] -= v.to_i}}.
tap{|h| h.each{|k,v| h[k] = h[k].to_s }}
返回{"Lima, Peru"=>"-3", "Chicago, IL"=>"5", "Krakow, Poland"=>"3"}