Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to push keys and values into an empty hash w/ Ruby?

Tags:

ruby

hash

I have a dictionary class and want to be able to push keys (as keywords) and values (as definitions) into an empty hash with an 'add' method. I don't understand how to syntactically write that. I have included an RSPEC file too.

ruby:

 class Dictionary
     attr_accessor :keyword, :definition
     def entries
          @hash = {}
     end
     def add(options)
          options.map do |keyword, definition|
               @hash[keyword.to_sym] = definition
          end
     end
 end

Rspec:

 require 'dictionary'

   describe Dictionary do
   before do
       @d = Dictionary.new
   end
   it 'can add whole entries with keyword and definition' do
       @d.add('fish' => 'aquatic animal')
       @d.entries.should == {'fish' => 'aquatic animal'}
       @d.keywords.should == ['fish']
   end

Any help is appreciated. Thank you!

UPDATE: Thank you Dave Newton for replying. I used your code and got this error:

ERROR:

 *Failure/Error: @d.keywords.should == ['fish']
 NoMethodError:
 undefined method `keywords' for #<Dictionary:0x007fb0c31bd458 
 @hash={"fish"=>"aquatic animal"}>*

I get a different error when I convert 'word' into a symbol using @hash[word.to_sym] = defintion

 *Failure/Error: @d.entries.should == {'fish' => 'aquatic animal'}
   expected: {"fish"=>"aquatic animal"}
        got: {:fish=>"aquatic animal"} (using ==)
   Diff:
   @@ -1,2 +1,2 @@
   -"fish" => "aquatic animal"
   +:fish => "aquatic animal"*
like image 808
andy4thehuynh Avatar asked Feb 22 '13 22:02

andy4thehuynh


People also ask

How do you add a value to a hash in Ruby?

Hash literals use the curly braces instead of square brackets and the key value pairs are joined by =>. For example, a hash with a single key/value pair of Bob/84 would look like this: { "Bob" => 84 }. Additional key/value pairs can be added to the hash literal by separating them with commas.

How do you push values into an array of hash in Ruby?

Creating an array of hashes You are allowed to create an array of hashes either by simply initializing array with hashes or by using array. push() to push hashes inside the array. Note: Both “Key” and :Key acts as a key in a hash in ruby.

How do you push to hash?

To append a new value to the array of values associated with a particular key, use push : push @{ $hash{"a key"} }, $value; The classic application of these data structures is inverting a hash that has many keys with the same associated value. When inverted, you end up with a hash that has many values for the same key.


2 Answers

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.

like image 93
Dave Newton Avatar answered Oct 19 '22 05:10

Dave Newton


Looking at your Rspec, It looks like you need this setup.

class Dictionary
  def initialize
    @hash = {}
  end

  def add(key_value)
    key_value.each do |key, value|
      @hash[key] = value
    end
  end

  def entries
     @hash
  end

  def keywords
     @hash.keys
  end

end

Do not use key.to_sym in add method, just key

To give flexibility to add method, I can return the self object to continuesly add.

def add(key_value)
  key_value.each do |key, value|
    @hash[key] = value
  end
  self
end

So, I can do this now.

@d.add("a" => "apple").add("b" => "bat")
like image 21
Abibullah Rahamathulah Avatar answered Oct 19 '22 04:10

Abibullah Rahamathulah