如何计算两个哈希值之间的增量?

时间:2014-11-08 11:32:37

标签: ruby-on-rails ruby hash

我想计算我的统计数据的增量。我已经尝试过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

3 个答案:

答案 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"}