Subtract two hashes in Ruby

Is it possible to change the hash class so that given two hashes, a new hash can be created containing only keys that are present in one hash, but not in the other?

eg:.

 h1 = {"Cat" => 100, "Dog" => 5, "Bird" => 2, "Snake" => 10} h2 = {"Cat" => 100, "Dog" => 5, "Bison" => 30} h1.difference(h2) = {"Bird" => 2, "Snake" => 10} 

Optionally, the difference method can include any key / value pairs, so the key is present in both hashes, but the value is different between them.

+6
source share
4 answers

Use the reject method:

 class Hash def difference(other) reject do |k,v| other.has_key? k end end end 

Only reject key / value pairs if the values ​​are identical (as suggested by mallanaga via a comment on my original answer that I deleted):

 class Hash def difference(other) reject do |k,v| other.has_key?(k) && other[k] == v end end end 

+6
source
 h1 = {"Cat" => 100, "Dog" => 5, "Bird" => 2, "Snake" => 10} h2 = {"Cat" => 999, "Dog" => 5, "Bison" => 30} 

Case 1: save all key / value pairs k=>v in h1 for which there is no k key in h2

This is one way:

 h1.dup.delete_if { |k,_| h2.key?(k) } #=> {"Bird"=>2, "Snake"=>10} 

This is different:

 class Array alias :spaceship :<=> def <=>(o) first <=> o.first end end (h1.to_a - h2.to_a).to_h #=> {"Bird"=>2, "Snake"=>10} class Array alias :<=> :spaceship remove_method(:spaceship) end 

Case 2: store all key / value pairs in h1 that are not in h2

All you need for this:

 (h1.to_a - h2.to_a).to_h #=> {"Cat"=>100, "Bird"=>2, "Snake"=>10} 

The # to_h array was introduced in Ruby 2.0. For earlier versions, use Hash [] .

+11
source

You can do it:

 h2.each_with_object(h1.dup){|(k, v), h| h.delete(k)} 
+2
source

try using the hashdiff hard drive.

 diff=HashDiff.diff(h1,h2) 
+1
source

Source: https://habr.com/ru/post/971939/


All Articles