I have 2 hashes (that later will be converted to array, not sure if this is relevant):
Hash1 = {"X"=>2, "Y"=>1, "Z"=>1}
Hash2 = {"X"=>1, "Y"=>1}
I need to subtract them like (Hash3 = Hash1 - Hash2), and I need the result of Hash3 to be, in this case :
Hash3 = {"X"=>1, "Y"=>0, "Z"=>1}
All examples and answers I've seen led to results where the key which had value equals 0 (Y) to be absent in the resulting hash, which is not what I need.
I'm using Ruby 2.3.3 and Rails 5.0
You can merge
them:
h1 = {"X"=>2, "Y"=>1, "Z"=>1}
h2 = {"X"=>1, "Y"=>1}
h1.merge(h2) { |k, v1, v2| v1 - v2 }
#=> {"X"=>1, "Y"=>0, "Z"=>1}
Whenever a key is present in both hashes, the block is called to determine the new value.
Due to this behavior it will not result in negative values if a key is only present in h2
:
h1 = {"X"=>2, "Y"=>1}
h2 = {"X"=>1, "Y"=>1, "Z"=>1}
h1.merge(h2) { |k, v1, v2| v1 - v2 }
#=> {"X"=>1, "Y"=>0, "Z"=>1}
You might expect:
#=> {"X"=>1, "Y"=>0, "Z"=>-1}
Which is what tadman's solution would return.
It's not too difficult if you break it down into two steps:
def hash_sub(a, b)
(a.keys + b.keys).uniq.map do |k|
[ k, a[k].to_i - b[k].to_i ]
end.to_h
end
hash_sub({"X"=>2, "Y"=>1, "Z"=>1}, {"X"=>1, "Y"=>1})
# => {"X"=>1, "Y"=>0, "Z"=>1}
The first step is to compute all the possible (unique) keys by combining the keys from the two hashes, and then convert to a new hash by subtracting one from the other, forcing conversion to an integer with .to_i
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With