在Ruby中减去两个哈希值

Kyl*_*and 7 ruby hash

是否可以hash修改类以便给定两个哈希值,可以创建仅包含一个哈希中存在但不存在另一个哈希值的新哈希值?

例如:

h1 = {"Cat" => 100, "Dog" => 5, "Bird" => 2, "Snake" => 10}

h2 = {"Cat" => 100, "Dog" => 5, "Bison" => 30}

h1.difference(h2) = {"Bird" => 2, "Snake" => 10}
Run Code Online (Sandbox Code Playgroud)

可选地,该difference方法可以包括任何键/值对,使得键存在于两个哈希中,但是它们之间的值不同.

Car*_*and 15

h1 = {"Cat" => 100, "Dog" => 5, "Bird" => 2, "Snake" => 10}
h2 = {"Cat" => 999, "Dog" => 5, "Bison" => 30}
Run Code Online (Sandbox Code Playgroud)

案例1:将所有键/值对k=>vh1对此有没有钥匙kh2

这是一种方式:

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

这是另一个:

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
Run Code Online (Sandbox Code Playgroud)

情况2:保留h1不在的所有键/值对h2

你需要的只是:

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

Array#to_h是在Ruby 2.0中引入的.对于早期版本,请使用Hash [].


Kyl*_*and 6

使用reject方法:

class Hash
  def difference(other)
    reject do |k,v|
      other.has_key? k
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

如果值相同,则仅拒绝键/值对(根据mallanaga的建议,通过对我原始答案的评论,我已删除):

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