Fork, clone, branch (training), bundle install
By the end of this, students should be able to:
- Constrast Ruby Hashes with JavaScript dictionaries.
- Create a Ruby Hash using both the implicit (
{}
) andnew
constructors. - Assign a value to or modify a value in a Ruby Hash using a specified key.
- Access a value in a Ruby Hash using a specified key.
- Obtain an Array of keys from a Ruby Hash.
- Explain why Symbols are preferred over Strings as keys in a Ruby Hash.
In Ruby, "A Hash is a dictionary-like collection of unique keys and their values". In sharp contrast to JavaScript, Ruby Hashes are not the most general object in the language, but are instances of a specialized class for key/value storage.
A Symbol is a sequence of characters that is stored at most once in any instance of the Ruby interpreter.
In Ruby, strings are compared a character at a time, but symbols are compared by object_id
. This makes comparing symbols fast and therefore much more performant than strings when used as keys in a Hash
.
Each of the following pairs of operations are equivalent:
> 'bob'.equal? 'bob'
=> false
> 'bob'.object_id == 'bob'.object_id
=> false
> 'bob'.eql? 'bob'
=> true
> 'bob' == 'bob'
=> true
But all of the following operations are equivalent:
> :bob.equal? :bob
=> true
> :bob.object_id == :bob.object_id
=> true
> :bob.eql? :bob
=> true
> :bob == :bob
=> true
We can create a symbol with arbitrary characters if we surround the characters with quotes (either :'<characters>'
or '<characters>'.to_sym
):
> :'&foo'.equal? '&foo'.to_sym
=> true
How does this compare to keys in JavaScript?
Let's look at different ways to create a Hash.
> consultant = {}
=> {}
> consultant = Hash.new
=> {}
> consultant = Hash.new('')
=> {}
> consultant.default = ''
=> ""
> consultant[:surname]
=> ""
> consultant
=> {}
> consultant = { given_name: 'Antony', surname: 'Donovan', height: 76}
=> {:given_name=>"Antony", :surname=>"Donovan", :height=>76}
> consultant[:weight] += 10
NoMethodError: undefined method ``+'' for nil:NilClass
from (pry):2:in ``__pry__''
> consultant = Hash.new(0).merge({ given_name: 'Antony', surname: 'Donovan', height: 76})
=> {:given_name=>"Antony", :surname=>"Donovan", :height=>76}
> consultant[:weight] += 10
=> 10
Picking sensible defaults may not always be easy.
Let's use the different forms of Hash::new to create some hashes in bin/code_along.rb
.
In bin/lab.rb
create a hash using the shorthand syntax for assigning the keys :education
and :experience
with the string "GA WDI". Then assign a default of []
to the hash and make sure that accessing non-existing keys return the default.
> consultant[:weight]
=> 0
> consultant[:weight] = 185
=> 185
> consultant[:weight] += 5
=> 190
> consultant[:surname]
=> "Donovan"
> consultant[:surname].prepend 'O\''
=> "O'Donovan"
> consultant[:surname]
=> "Donovan"
> consultant[:surname] = consultant[:surname].prepend 'O\''
=> "O'Donovan"
> consultant[:surname]
=> "O'Donovan"
To get an Array of the keys that have been set in a hash, use Hash#keys
.
> consultant.keys
=> [:given_name, :surname, :height, :weight]
A quick look at access and assignment in bin/code_along.rb
.
Append " Boston"
to both :experience
and :education
in the hash in bin/lab.rb
. Append one or more item of your choosing to the values at each of these keys.
In bin/lab.rb
initialize Hash.new
with a block so that if a key is searched for and does not exist, then it will automatically be placed in the hash with a default value.
Source code distributed under the MIT license. Text and other assets copyright General Assembly, Inc., all rights reserved.