Ruby Hashes Flashcards
hash
A hash is a data structure that stores items by associated keys. This is contrasted against arrays, which store items by an ordered index. Entries in a hash are often referred to as key-value pairs. This creates an associative representation of data.
a hash is created using symbols as keys and any data types as values. All key-value pairs in a hash are surrounded by curly braces {} and comma separated.
irb :001 > old_syntax_hash = {:name => ‘bob’}
=> {:name=>’bob’}
The newer syntax is introduced in Ruby version 1.9 and is much simpler. As you can see, the result is the same.
irb :002 > new_hash = {name: ‘bob’}
=> {:name=>’bob’}
many key-value pairs.
irb :003 > person = { height: ‘6 ft’, weight: ‘160 lbs’ }
=> {:height=>’6 ft’, :weight=>’160 lbs’}
add to hash
irb :003 > person = { height: ‘6 ft’, weight: ‘160 lbs’ }
=> {:height=>’6 ft’, :weight=>’160 lbs’}
irb :004 > person[:hair] = ‘brown’
=> “brown”
irb :005 > person
=> {:height=>’6 ft’, :weight=>’160 lbs’, :hair=>’brown’}
irb :006> person[:age] = 62
=> 62
irb :007> person
=> {:height=>’6 ft’, :weight=>’160 lbs’, :hair=>’brown’, :age=>62}
remove from a hash
irb :008 > person.delete(:age)
=> 62
irb :009 > person
=> {:height=>’6 ft’, :weight=>’160 lbs’, :hair=>’brown’}
retrieve info from a hash
irb :010 > person[:weight]
=> “160 lbs”
merge two hashes
irb :011 > person.merge!(new_hash)
=> {:height=>’6 ft’, :weight=>’160 lbs’, :hair=>’brown’, :name=>’bob’}
Notice that we used the bang operator (!) to make this change destructive. We could have chosen to use the merge method instead, which would have returned a new merged hash, but left the original person hash unmodified.
.empty?
a method to detect whether something has any values or not.
Hashes vs. Arrays
When deciding whether to use a hash or an array, ask yourself a few questions:
Does this data need to be associated with a specific label? If yes, use a hash. If the data doesn’t have a natural label, then typically an array will work fine.
Does order matter? If yes, then use an array. As of Ruby 1.9, hashes also maintain order, but usually ordered items are stored in an array.
Do I need a “stack” or a “queue” structure? Arrays are good at mimicking simple “first-in-first-out” queues, or “last-in-first-out” stacks.
has_key? method
The has_key? method allows you to check if a hash contains a specific key. It returns a boolean value.
irb :001 > name_and_age = { “Bob” => 42, “Steve” => 31, “Joe” => 19}
=> {“Bob”=>42, “Steve”=>31, “Joe”=>19}
irb :002 > name_and_age.has_key?(“Steve”)
=> true
irb :003 > name_and_age.has_key?(“Larry”)
=> false
select method
The select method allows you to pass a block and will return any key-value pairs that evaluate to true when ran through the block.
irb :004 > name_and_age.select { |k,v| k == “Bob” }
=> {“Bob”=>42}
irb :005 > name_and_age.select { |k,v| (k == “Bob”) || (v == 19) }
=> {“Bob”=>42, “Joe”=>19}
fetch method
The fetch method allows you to pass a given key and it will return the value for that key if it exists. You can also specify an option for return if that key is not present.
irb :006 > name_and_age.fetch("Steve") => 31 irb :007 > name_and_age.fetch("Larry") => KeyError: key not found: "Larry" from (irb):32:in `fetch' from (irb):32 from /usr/local/rvm/rubies/ruby-2.0.0-rc2/bin/irb:16:in `' irb :008 > name_and_age.fetch("Larry", "Larry isn't in this hash") => "Larry isn't in this hash"
to_a method
The to_a method returns an array version of your hash when called. Let’s see it in action. It doesn’t modify the hash permanently though.
irb :009 > name_and_age.to_a
=> [[“Bob”, 42], [“Steve”, 31], [“Joe”, 19]]
irb :010 > name_and_age
=> {“Bob”=>42, “Steve”=>31, “Joe”=>19}
.keys or .values
if you want to just retrieve all the keys or all the values out of a hash
irb :0011 > name_and_age.keys
=> [“Bob”, “Steve”, “Joe”]
irb :0012 > name_and_age.values
=> [42, 31, 19]