This part of the Ruby tutorial will mention Ruby hashes. A hash is a collection of key-value pairs. It is similar to an array. Unlike arrays, hashes can have arbitrary objects as indexes. Arrays have can only have integers. Hashes are sometimes called associated arrays.
Hashes are powerful collections. They have many methods that programmers can use to do their work.
A
In the third script, we create a hash with the hash literal notation. The values are bound by the curly brackets. And the key-value pairs are associated with the => characters.
The second example of the section presents three distinct hash methods.
We have methods that can determine, whether a key or a value is present in the hash.
In the final example of the section, we will read values from the hash.
The
In this chapter, we worked with Ruby hashes.
Hashes are powerful collections. They have many methods that programmers can use to do their work.
Hash creation
A hash can be created in two basic ways. Either with thenew
keyword or by utilizing the hash literal. #!/usr/bin/rubyThe first script creates a hash and adds two key-value pairs into the hash object.
names = Hash.new
names[1] = "Jane"
names[2] = "Thomas"
puts names
names = Hash.newA hash object is created.
names[1] = "Jane"We add two pairs of values to the hash. The 1, 2 numbers are the keys to the hash. The keys are placed inside the square brackets. The names are the values that belong to the keys.
names[2] = "Thomas"
puts namesThe
puts
method prints the string representation of the hash to the console. It is also the string literal of the hash. $ ./create.rbFrom the output we can see the literal representation of the names hash. A hash is bouded by curly brackets. The keys and the values are paired with the => characters.
{1=>"Jane", 2=>"Thomas"}
A
store
method can be used to initialize the hash with some values. It can be use instead of the square brackets. #!/usr/bin/rubyWe have a similar script. This time we use the
names = Hash.new
names.store(1, "Jane")
names.store(2, "Thomas")
names.store(3, "Rebecca")
puts names
store
method. The method associates the given key with the given value and stores the pair in the hash. names.store(1, "Jane")The first parameter of the
store
method is the key and the second parameter is the value. In the third script, we create a hash with the hash literal notation. The values are bound by the curly brackets. And the key-value pairs are associated with the => characters.
#!/usr/bin/rubyWe create a domains hash with 5 pairs. This time both keys and values are string types.
domains = { "de" => "Germany",
"sk" => "Slovakia",
"hu" => "Hungary",
"us" => "United States",
"no" => "Norway"
}
puts domains["de"]
puts domains["sk"]
domains = { "de" => "Germany",This is a hash literal notation. The key-value pairs are put between the curly brackets. The items are separated by the comma character. And the keys are associated with values using the => characters combination.
"sk" => "Slovakia",
"hu" => "Hungary",
"us" => "United States",
"no" => "Norway"
}
puts domains["de"]Here we print the domain value name associated with the "de" key.
$ ./create3.rbOutput of the code example.
Germany
Slovakia
Basic work
In this section, we will present some methods for the very basic work with Ruby hashes.#!/usr/bin/rubyIn the above Ruby script, we create a hash with five values. We introduce three hash methods.
names = Hash.new
names[1] = "Jane"
names[2] = "Thomas"
names[3] = "Robert"
names[4] = "Julia"
names[5] = "Rebecca"
puts "The size of the hash is #{names.size}"
puts names.keys.inspect
puts names.values.inspect
puts "The size of the hash is #{names.size}"The
size
method returns the size of the hash. It is a synonym for the length
method. puts names.keys.inspectThe
puts names.values.inspect
keys
method returns all keys of the hash. In a similar fashion, the values
method returns all the values of the hash. The returned data is in the form of an array. To have a more readable output, we also call the inspect
method on the returned arrays. $ ./basic.rbOuput of the example. Note that the output of the last two methods are two arrays.
The size of the hash is 5
[1, 2, 3, 4, 5]
["Jane", "Thomas", "Robert", "Julia", "Rebecca"]
The second example of the section presents three distinct hash methods.
#!/usr/bin/rubyThe Ruby script creates a names hash. It calls three hash methods on the object.
names1 = Hash.new
names1[1] = "Jane"
names1[2] = "Thomas"
names1[3] = "Robert"
names1[4] = "Julia"
names1[5] = "Rebecca"
names2 = names1.dup
puts names1.eql? names2
puts names1.empty?
names1.clear
puts names1.empty?
names2 = names1.dupWe create a duplicate of the hash by calling the
dup
method. The method is inherited by the hash from the parent object. puts names1.eql? names2The
eql?
method compares two hash objects. In our case the hashes are equal and the line prints true. puts names1.empty?The
empty?
method checks whether the hash is empty or not. The line print false. Because the names1 hash has five items. names1.clearThe
puts names1.empty?
clear
method deletes all items from the hash. The successive call of the empty?
method returns true. $ ./basic2.rbExample output.
true
false
true
We have methods that can determine, whether a key or a value is present in the hash.
#!/usr/bin/rubyWe create a domains hash with four pairs. The keys are symbols. Symbols are often used as keys, because they are more efficient.
domains = { :de => "Germany", :sk => "Slovakia",
:no => "Norway", :us => "United States"
}
puts domains.has_key? :de
puts domains.include? :no
puts domains.key? :me
puts domains.member? :sk
puts domains.has_value? "Slovakia"
puts domains.value? "Germany"
puts domains.has_key? :deHere we have four methods that determine, whether a key is in the hash. They all do the same; they are synonyms.
puts domains.include? :no
puts domains.key? :me
puts domains.member? :sk
puts domains.has_value? "Slovakia"These two methods check if the two strings are inside the hash.
puts domains.value? "Germany"
$ ./has.rbThis is the output of the example.
true
true
false
true
true
true
In the final example of the section, we will read values from the hash.
#!/usr/bin/rubyThe Ruby script presents three hash methods for reading values of a hash.
stones = { 1 => "garnet", 2 => "topaz",
3 => "opal", 4 => "amethyst"
}
puts stones.fetch 1
puts stones[2]
puts stones.values_at 1, 2, 3
puts stones.fetch 1The
fetch
method reads a value for a given key. puts stones[2]Square brackets can be used to get a value. In our case, the line prints "topaz" to the console.
puts stones.values_at 1, 2, 3The
values_at
method can be used to get multiple values at one step. The method returns an array of the values for the given keys. $ ./read.rbOutput of the example.
garnet
topaz
garnet
topaz
opal
Looping through a hash
There are several methods that can be used to loop through a Ruby hash.#!/usr/bin/rubyIn the above example, we present four methods. We use them to display all keys, values and both keys and values of a hash.
stones = { 1 => "garnet", 2 => "topaz",
3 => "opal", 4 => "amethyst"
}
stones.each { |k, v| puts "Key: #{k}, Value: #{v}" }
stones.each_key { |key| puts "#{key}" }
stones.each_value { |val| puts "#{val}" }
stones.each_pair { |k, v| puts "Key: #{k}, Value: #{v}" }
stones.each { |k, v| puts "Key: #{k}, Value: #{v}" }The
each
method calls the given block for each key in the hash, passing key-value pair as parameter. stones.each_key { |key| puts "#{key}" }We use the
each_key
method to loop throug all keys of a hash. They are printed to the console. stones.each_value { |val| puts "#{val}" }The
each_value
can be used to loop throug the values of a hash. stones.each_pair { |k, v| puts "Key: #{k}, Value: #{v}" }The
each_pair
method is a synonym for the each
method. We loop through the keys and values of the stones hash. $ ./loop.rbThe output shows the keys and values, keys, values of the stones hash.
Key: 1, Value: garnet
Key: 2, Value: topaz
Key: 3, Value: opal
Key: 4, Value: amethyst
1
2
3
4
garnet
topaz
opal
amethyst
Key: 1, Value: garnet
Key: 2, Value: topaz
Key: 3, Value: opal
Key: 4, Value: amethyst
Deleting pairs
In the following examples, we will concern ourselves with methods that delete pairs from the hashes. There are methods that delete only a pair at a time and methods, that can delete multiple key-values at one step.#!/usr/bin/rubyIn the script we have two methods. The
names = Hash.new
names[1] = "Jane"
names[2] = "Thomas"
names[3] = "Robert"
names[4] = "Julia"
names[5] = "Rebecca"
names.delete 4
names.shift
puts names
delete
method and the shift
method. The delete
method removes and returns a value for a specified key. The shift
method deletes the first pair from the hash. It also returns the removed pair as an array. names.delete 4Here we delete a pair 4 => "Julia".
names.shiftThis code line removes the first pair, namely 1 => "Jane".
$ ./deleteitem.rbIn the output we can see the pairs of the hash that are left.
{2=>"Thomas", 3=>"Robert", 5=>"Rebecca"}
The
reject
and the delete_if
methods can remove multiple pairs from a hash. The methods delete pairs that return true for the given condition in the block. There is an important distinction between the two methods. The reject
method works on a copy of a hash while the delete_if
works on the original hash. #!/usr/local/bin/rubyThe example deletes multiple pairs using the previously mentioned methods.
names1 = Hash.new
names1[1] = "Jane"
names1[2] = "Thomas"
names1[3] = "Robert"
names1[4] = "Julia"
names1[5] = "Rebecca"
puts names1.reject { |k, v| v =~ /R.*/ }
puts names1
puts names1.delete_if { |k, v| k<=3 }
puts names1
puts names1.reject { |k, v| v =~ /R.*/ }The
reject
method removes all values that fit the regular expression in the block. The modified hash is returned and the original hash is not changed. puts names1The output of this line confirms, that the original hash was intact.
puts names1.delete_if { |k, v| k<=3 }In this case, we delete all pairs, for which the key is lower or equal to 3. The method modifies the original hash.
$ ./massdelete.rbOutput of the example.
{1=>"Jane", 2=>"Thomas", 4=>"Julia"}
{1=>"Jane", 2=>"Thomas", 3=>"Robert", 4=>"Julia", 5=>"Rebecca"}
{4=>"Julia", 5=>"Rebecca"}
{4=>"Julia", 5=>"Rebecca"}
Adding hashes
Ruby has methods for hash addition. Themerge
and the update
methods. #!/usr/bin/rubyIn the Ruby script, we create two hashes. Then we apply
names1 = Hash.new
names1[1] = "Jane"
names1[2] = "Thomas"
names2 = Hash.new
names2[3] = "Robert"
names2[4] = "Julia"
names = names1.merge names2
puts names
names = names1.update names2
puts names
merge
and update
methods on them. names = names1.merge names2We add two hashes, the names1 and the names2 and the result is assigned to the names hash. We print the newly created hash.
puts names
$ ./merge.rbAs we can see, the final hashes contain pairs from the names1 and names2 hashes.
{1=>"Jane", 2=>"Thomas", 3=>"Robert", 4=>"Julia"}
{1=>"Jane", 2=>"Thomas", 3=>"Robert", 4=>"Julia"}
The merge vs merge!
In the final section, we recap a common ruby thing. Several methods have their counterparts, that end with an explamation mark. The mark has no syntactical meaning. It is a Ruby idiom. It hints a programmer, that the method will actually modify an object, on which the method is called.#!/usr/bin/rubyWe will demonstrate the difference on the
names1 = Hash.new
names1[1] = "Jane"
names1[2] = "Thomas"
names2 = Hash.new
names2[3] = "Robert"
names2[4] = "Julia"
names = names1.merge names2
puts names
puts names1
names = names1.merge! names2
puts names
puts names1
merge
and merge!
methods. names = names1.merge names2The
merge
does not modify the names1 hash. It works on its copy. names = names1.merge! names2The
merge!
method works on the original hash. The names1 hash is changed. $ ./merge2.rbOutput.
{1=>"Jane", 2=>"Thomas", 3=>"Robert", 4=>"Julia"}
{1=>"Jane", 2=>"Thomas"}
{1=>"Jane", 2=>"Thomas", 3=>"Robert", 4=>"Julia"}
{1=>"Jane", 2=>"Thomas", 3=>"Robert", 4=>"Julia"}
In this chapter, we worked with Ruby hashes.
0 comments:
Post a Comment