Subtracting hashes in ruby
I have 2 hashes (which will later be converted to an array, not sure if this is relevant):
Hash1 = {"X"=>2, "Y"=>1, "Z"=>1}
Hash2 = {"X"=>1, "Y"=>1}
I need to subtract them as (Hash3 = Hash1 - Hash2) and I want the result of Hash3, in this case:
Hash3 = {"X"=>1, "Y"=>0, "Z"=>1}
All the examples and answers I have seen resulted in results where the key that mattered was 0 (Y) was missing from the resulting hash, which is not what I want.
I am using Ruby 2.3.3 and Rails 5.0
source to share
You can merge
:
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.
As a result, this behavior will not result in negative values ββif the 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 can expect:
#=> {"X"=>1, "Y"=>0, "Z"=>-1}
This is what tadman's solution will return.
source to share
It's not too difficult if you split it 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 possible (unique) keys by concatenating the keys from the two hashes, and then convert to a new hash by subtracting one from the other, forcing the conversion to an integer c .to_i
.
source to share