C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
First: We add 3 string keys that have integer values. Theses are key-value pairs.
Brackets: We use the square brackets, "[" and "]" to specify the key. The value we add is indicated by assignment.
Ruby program that creates a hash
# Create a new hash.
items = Hash.new()
# Store these key-value pairs in it.
items["milk"] = 5
items["eggs"] = 10
items["bread"] = 15
# Display the values.
puts items["milk"]
puts items["eggs"]
puts items["bread"]
Output
5
10
15
Also: We use values of type integer (32) and of type string ("medium") in the hash. A hash is flexible and can contain different types.
Ruby program that uses default value
# Use the default value of -1.
sizes = Hash.new(-1)
# Add keys and values.
sizes["jeans"] = 32
sizes["shirt"] = "medium"
# Access existing data.
puts sizes["jeans"]
puts sizes["shirt"]
# This doesn't exist.
puts sizes["jacket"]
Output
32
medium
-1
Note: Before the delete() method is called, there are four elements. After it is invoked, there are only three.
Ruby program that uses count, delete
# Add data to the new hash.
elements = Hash.new()
elements[100] = "a"
elements[200] = "b"
elements[300] = "c"
elements[400] = "d"
# Display count.
print "Count: ", elements.count(), "\n"
# Delete a key and its value.
elements.delete(100)
# Display new count.
print "Count: ", elements.count(), "\n"
Output
Count: 4
Count: 3
Here: We delete keys of length greater than 3. The key "rabbit" is deleted, but the other two ("cat" and "dog") remain.
Note: We can also delete based on the value. Just test the second parameter in the block.
Ruby program that uses delete_if
# A hash with three pairs.
values = {"cat" => 1, "dog" => 2, "rabbit" => 4}
# Delete keys longer than 3 chars.
values.delete_if{|key, value| key.length > 3}
puts values
Output
{"cat"=>1, "dog"=>2}
Ruby program that uses keys, for-loop
# Add names.
names = Hash.new()
names["charlotte"] = "stant"
names["maggie"] = "verver"
names["adam"] = "verver"
# Use for-loop on keys.
for key in names.keys()
print key, "/", names[key], "\n"
end
Output
charlotte/stant
maggie/verver
adam/verver
Do: The each iterator requires the "do" keyword if you do not place the entire statement on one line.
Each_pair: The each_pair method is aliased to each. There is no advantage in using it. In my experience, each is more standard.
Ruby program that uses each, hash
numbers = {10 => 100, 20 => 200, 30 => 300}
# Use each to enumerate the pairs in the hash.
numbers.each do |key, value|
# Display the key and value.
print " KEY: ", key, "\n"
print "VALUE: ", value, "\n"
end
Output
KEY: 10
VALUE: 100
KEY: 20
VALUE: 200
KEY: 30
VALUE: 300
Ruby program that uses each, one-line
numbers = {100 => "A", 200 => "B", 300 => "C"}
# Use each with one-line syntax.
numbers.each {|k, v| print k, " ", v, "\n"}
Output
100 A
200 B
300 C
Tip: In some program logic, testing to see if a hash is empty may help performance. We can avoid testing for specific keys.
Ruby program that uses empty method
# New hash.
items = Hash.new()
# Check emptiness.
if items.empty?
puts "Empty"
end
# Add something.
items["sam"] = 1
# It is no longer empty.
if !items.empty?
puts "Not empty"
end
Output
Empty
Not empty
Duplicates: The resulting merged hash has only one value for "b"—this is 2. But in the hashes, the key "b" has two values, 2 and 3.
So: The duplicate value was lost in the merged hash. This could be a problem if there are two valid values.
Ruby program that merges hashes
# Two input hashes.
one = Hash["a" => 1, "b" => 2]
two = Hash["b" => 3, "c" => 0, "d" => 3]
# Merge them into a third.
both = two.merge(one)
# Display result.
puts both
Output
{"b"=>2, "c"=>0, "d"=>3, "a"=>1}
Then: We can use a fast lookup on a value to get its original key. And this optimizes certain program requirements.
Ruby program that inverts a hash
# Create a hash and invert it.
one = Hash["a" => 1, "b" => 2]
two = one.invert()
# Display both hashes.
puts one
puts two
Output
{"a"=>1, "b"=>2}
{1=>"a", 2=>"b"}
Note: These methods are fast—they just perform a lookup. Two methods in Ruby, member and include, are equivalent.
Ruby program that checks keys for existence
# A hash of utensils
silverware = Hash["spoon" => 10, "fork" => 20]
# See if key exists.
if silverware.key?("fork")
puts "Found: fork"
end
# Check that key does not exist.
if !silverware.has_key?("knife")
puts "Not found: knife"
end
Output
Found: fork
Not found: knife
Tip: Flatten has the same effect as calling keys() and values() and then combining the two into a third array.
However: It is better to use flatten() when this combined data structure is required—it is simpler.
Ruby program that calls flatten
# Create and flatten a hash.
numbers = Hash[1 => 10, 2 => 20, 3 => 30]
flat = numbers.flatten()
# Display flattened array.
puts flat
Output
1
10
2
20
3
30
Here: Three hashes are created. The first hash, fruit1, is equal to the third hash, fruit3. But the second hash is not equal.
Ruby program that uses eql
# Create three hashes.
fruit1 = Hash["apple" => 1, "pear" => 2]
fruit2 = Hash["guava" => 3, "apricot" => 4]
fruit3 = Hash["pear" => 2, "apple" => 1]
# See if first hash equals second hash.
if !fruit1.eql?(fruit2)
puts "1 not equal to 2"
end
# First hash equals third hash.
# ... Ordering does not matter.
if fruit1.eql?(fruit3)
puts "1 equals 3"
end
Output
1 not equal to 2
1 equals 3
Note: With inspect(), we can make further changes to the hash but keep the same string.
Characters: The string representation returned by inspect() uses the => characters to separate keys and values.
Ruby program that uses inspect
# An input hash.
values = ["a" => 10, "b" => 20];
# Convert to string.
s = values.inspect
# Display the string.
puts s
# String length.
puts s.length
Output
[{"a"=>10, "b"=>20}]
20
Here: We create a hash with two nested hashes in it. Then we perform lookups on the hash located at "cat" and the one at "dog."
Ruby program that uses nested hash
lookup = Hash[]
# Create and add a subhash.
subhash = Hash[]
subhash["paws"] = 4
subhash["fur"] = "orange"
lookup["cat"] = subhash
# Create another subhash.
subhash = Hash[]
subhash["tail"] = 1
subhash["ears"] = 2
lookup["dog"] = subhash
# Display nested hashes.
puts lookup["cat"]
puts lookup["dog"]
# Get values from nested hashes.
puts lookup["cat"]["paws"]
puts lookup["dog"]["ears"]
Output
{"paws"=>4, "fur"=>"orange"}
{"tail"=>1, "ears"=>2}
4
2
Ruby program that sorts on keys
plants = {"carrot" => 5, "turnip" => 10, "apple" => 8}
# Sort the hash by its keys.
plants.sort.each do |key, value|
# Display the entry.
puts key + ": " + String(value)
end
Output
apple: 8
carrot: 5
turnip: 10
Note: There is no in-place sorting method on a hash. Calling "sort!" causes an error. We must always copy into a new variable.
Ruby program that sorts on values
plants = {"carrot" => 5, "turnip" => 10, "apple" => 8}
# Sort the hash by its values.
# ... Iterate over the resulting array.
result = plants.sort{|x, y| x[1] <=> y[1]}
result.each do |key, value|
puts String(value) + "..." + key
end
Output
5...carrot
8...apple
10...turnip
Version 1: In this code, we test lookups in a hash. We look up the string keys "two" and "four."
Version 2: In this version of the code, we search for those same elements in a similar Array.
Result: We find Hash improves performance. Even on a small collection of five elements, it locates about 50% faster than an array.
Ruby program that times hash, array
h = Hash["one" => 0, "two" => 1, "three" => 2,
"four" => 3, "five" => 4]
a = Array["one", "two", "three", "four", "five"]
count = 100000
n1 = Time.now.usec
# Version 1: perform hash lookups.
count.times do
# Two hash lookups.
v = h["four"]
v = h["two"]
end
n2 = Time.now.usec
# Version 2: perform array searches.
count.times do
# Two array find operations.
v = a.index("four")
v = a.index("two")
end
n3 = Time.now.usec
# Compute milliseconds total.
puts ((n2 - n1) / 1000)
puts ((n3 - n2) / 1000)
Output
55 ms Hash lookup
86 ms Array index