How to push keys and values into an empty hash w/ Ruby?
Instantiate your hash in Dictionary
's initialize
:
class Dictionary
def initialize
@hash = {}
end
def add(defs)
defs.each do |word, definition|
@hash[word] = definition
end
end
end
Right now you have no hash until you call entries
, which you don't.
entries
should return the existing hash, not create a new one.
keywords
should return the hash's keys.
You do not need accessors for keyword
and definition
. Such singular items are meaningless in a dictionary class. You might want something like lookup(word)
that returned a definition.
Also, you convert words to symbols, but I don't know why–particularly since you use string keys in your spec. Pick one, although I'm not convinced this is a case where symbols add value.
Please consider variable naming carefully to provide as much context as possible.
Pushing keys and values into a hash
Did you notice that your resulting hash also contains keys which should be values? That's because header_elements
is an array and you're trying to iterate it as a hash (which it isn't). In fact, you don't need to iterate it.
key, val = line.split(': ')
@headers[key] = val
Append key/value pair to hash with in Ruby
There is merge!
.
h = {}
h.merge!(key: "bar")
# => {:key=>"bar"}
How to add new item to hash
Create the hash:
hash = {:item1 => 1}
Add a new item to it:
hash[:item2] = 2
How do I append a key value pair to an existing hash in Ruby?
There are 3 ways:
.merge(other_hash)
Returns a new hash containing the contents of other_hash and the contents of hsh.
hash = { a: 1 }
puts hash.merge({ b: 2, c: 3 }) # => {:a=>1, :b=>2, :c=>3}
.merge!(other_hash)
Adds the contents of other_hash to hsh.
hash = { a: 1 }
puts hash.merge!({ b: 2, c: 3 }) # => {:a=>1, :b=>2, :c=>3}
And most efficient way is to modify existing hash, setting new values directly:
hash = { a: 1 }
hash[:b] = 2
hash[:c] = 3
puts hash # => {:a=>1, :b=>2, :c=>3}
Corresponding Benchmarks for these methods:
user system total real
0.010000 0.000000 0.010000 ( 0.013348)
0.010000 0.000000 0.010000 ( 0.003285)
0.000000 0.000000 0.000000 ( 0.000918)
Creating a Hash with values as arrays and default value as empty array
Lakshmi is right. When you created the Hash using Hash.new([])
, you created one array object.
Hence, the same array is returned for every missing key in the Hash.
That is why, if the shared array is edited, the change is reflected across all the missing keys.
Using:
Hash.new { |h, k| h[k] = [] }
Creates and assigns a new array for each missing key in the Hash, so that it is a unique object.
How to add to an existing hash in Ruby
If you have a hash, you can add items to it by referencing them by key:
hash = { }
hash[:a] = 'a'
hash[:a]
# => 'a'
Here, like [ ]
creates an empty array, { }
will create a empty hash.
Arrays have zero or more elements in a specific order, where elements may be duplicated. Hashes have zero or more elements organized by key, where keys may not be duplicated but the values stored in those positions can be.
Hashes in Ruby are very flexible and can have keys of nearly any type you can throw at it. This makes it different from the dictionary structures you find in other languages.
It's important to keep in mind that the specific nature of a key of a hash often matters:
hash = { :a => 'a' }
# Fetch with Symbol :a finds the right value
hash[:a]
# => 'a'
# Fetch with the String 'a' finds nothing
hash['a']
# => nil
# Assignment with the key :b adds a new entry
hash[:b] = 'Bee'
# This is then available immediately
hash[:b]
# => "Bee"
# The hash now contains both keys
hash
# => { :a => 'a', :b => 'Bee' }
Ruby on Rails confuses this somewhat by providing HashWithIndifferentAccess where it will convert freely between Symbol and String methods of addressing.
You can also index on nearly anything, including classes, numbers, or other Hashes.
hash = { Object => true, Hash => false }
hash[Object]
# => true
hash[Hash]
# => false
hash[Array]
# => nil
Hashes can be converted to Arrays and vice-versa:
# Like many things, Hash supports .to_a
{ :a => 'a' }.to_a
# => [[:a, "a"]]
# Hash also has a handy Hash[] method to create new hashes from arrays
Hash[[[:a, "a"]]]
# => {:a=>"a"}
When it comes to "inserting" things into a Hash you may do it one at a time, or use the merge
method to combine hashes:
{ :a => 'a' }.merge(:b => 'b')
# {:a=>'a',:b=>'b'}
Note that this does not alter the original hash, but instead returns a new one. If you want to combine one hash into another, you can use the merge!
method:
hash = { :a => 'a' }
# Returns the result of hash combined with a new hash, but does not alter
# the original hash.
hash.merge(:b => 'b')
# => {:a=>'a',:b=>'b'}
# Nothing has been altered in the original
hash
# => {:a=>'a'}
# Combine the two hashes and store the result in the original
hash.merge!(:b => 'b')
# => {:a=>'a',:b=>'b'}
# Hash has now been altered
hash
# => {:a=>'a',:b=>'b'}
Like many methods on String and Array, the !
indicates that it is an in-place operation.
Related Topics
Ruby String with Usd "Money" Converted to Number
How to Enable Compression in Ruby on Rails
API Errors Customization for Rails 3 Like Github API V3
Ruby - Create Singleton with Parameters
Active Admin: Sorting on Multiple Columns
Are There Any Ruby Orms Which Use Cursors or Smart Fetch
Rails 12 Hour Am/Pm Range for a Day
Regex to Match Hashtags in a Sentence Using Ruby
Sunspot_Rails Gem - " Errno:: Econnrefused (Connection Refused - Connect (2)) "
Discriminate First and Last Element in Each
Map an Array Modifying Only Elements Matching a Certain Condition
Solving the Travelling Salesman Problem in Ruby (50+ Locations)
Pretty Print to a File in Ruby
Rails Custom Validation - Only One Record Can Be True
How to Print Something Without a New Line in Ruby
Can Activerecord Connect to Postgresql Remotely and Protect the Db Password