Removing Elements from a Hash






Removing Elements from a Hash

Problem

Certain elements of your hash have got to go!

Solution

Most of the time you want to remove a specific element of a hash. To do that, pass the key into Hash#delete.

	h = {}
	h[1] = 10
	h                                          # => {1=>10}
	h.delete(1)
	h                                          # => {}

Discussion

Don't try to delete an element from a hash by mapping it to nil. It's true that, by default, you get nil when you look up a key that's not in the hash, but there's a difference between a key that's missing from the hash and a key that's present but mapped to nil. Hash#has_key? will see a key mapped to nil, as will Hash#each and all other methods except for a simple fetch:

	h = {}
	h[5]                                         # => nil
	h[5] = 10
	h[5]                                         # => 10
	h[5] = nil
	h[5]                                         # => nil
	h.keys                                       # => [5]
	h.delete(5)
	h.keys                                       # => []

Hash#delete works well when you need to remove elements on an ad hoc basis, but sometimes you need to go through the whole hash looking for things to remove. Use the Hash#delete_if iterator to delete key-value pairs for which a certain code block returns true (Hash#reject works the same way, but it works on a copy of the Hash). The following code deletes all key-value pairs with a certain value:

	class Hash
	  def delete_value(value)
	    delete_if { |k,v| v == value }
	  end
	end

	h = {'apple' => 'green', 'potato' => 'red', 'sun' => 'yellow',
	     'katydid' => 'green' }
	h.delete_value('green')
	h                                    # => {"sun"=>"yellow", "potato"=>"red"}

This code implements the opposite of Hash#merge; it extracts one hash from another:

	class Hash
	  def remove_hash(other_hash)
	    delete_if { |k,v| other_hash[k] == v }
	  end
	end

	squares = { 1 => 1, 2 => 4, 3 => 9 }
	doubles = { 1 => 2, 2 => 4, 3 => 6 }
	squares.remove_hash(doubles)
	squares                                  # => {1=>1, 3=>9}

Finally, to wipe out the entire contents of a Hash, use Hash#clear:

	h = {}
	1.upto(1000) { |x| h[x] = x }
	h.keys.size                              # => 1000
	h.clear
	h                                        # => {}

See Also

  • Recipe 5.3, "Adding Elements to a Hash"

  • Recipe 5.7, "Iterating Over a Hash"



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows