30

I have an array of hashes to write a generic checker for, so I want to pass in the name of a key to be checked. The hash was defined with keys with symbols (colon prefixes). I can't figure out how to use the variable as a key properly. Even though the key exists in the hash, using the variable to access it results in nil.

In IRB I do this:

>> family = { 'husband' => "Homer", 'wife' => "Marge" }
=> {"husband"=>"Homer", "wife"=>"Marge"}
>> somevar = "husband"
=> "husband"
>> family[somevar]
=> "Homer"
>> another_family  = { :husband => "Fred", :wife => "Wilma" }
=> {:husband=>"Fred", :wife=>"Wilma"}
>> another_family[somevar]
=> nil
>>

How do I access the hash key through a variable? Perhaps another way to ask is, how do I coerce the variable to a symbol?

2
  • 1
    "husband".to_sym => :husband. Commented Aug 27, 2014 at 22:33
  • @CarySwoveland Watch out for NoMethodError: undefined method `to_sym' for nil:NilClass when var is nil Commented Jan 24, 2019 at 2:04

5 Answers 5

50

You want to convert your string to a symbol first:

another_family[somevar.to_sym]

If you want to not have to worry about if your hash is symbol or string, simply convert it to symbolized keys

see: How do I convert a Ruby hash so that all of its keys are symbols?

Sign up to request clarification or add additional context in comments.

1 Comment

Do watch out for nil somevar, though.
7

You can use the Active Support gem to get access to the with_indifferent_access method:

require 'active_support/core_ext/hash/indifferent_access'
> hash = { somekey: 'somevalue' }.with_indifferent_access
 => {"somekey"=>"somevalue"}
> hash[:somekey]
 => "somevalue"
> hash['somekey']
=> "somevalue"

1 Comment

This uses ActiveSupport Core Extensions, which is the proper way to cherry-pick specific extensions.
3

Since your keys are symbols, use symbols as keys.

> hash = { :husband => 'Homer', :wife => 'Marge' }
 => {:husband=>"Homer", :wife=>"Marge"}
> key_variable = :husband
 => :husband
> hash[key_variable]
 => "Homer"

1 Comment

This might work in some circumstances, but in my case I'm passing them in as parameters, and Trollop (argument parsing gem) won't accept a symbol as a default value.
0

If you use Rails with ActiveSupport, then do use HashWithIndifferentAccess for flexibility in accessing hash with either string or symbol.

family = HashWithIndifferentAccess.new({
  'husband' => "Homer", 
  'wife' => "Marge"
})

somevar = "husband"
puts family[somevar]
#Homer

somevar = :husband
puts family[somevar]
#Homer

Comments

-1

The things that you see as a variable-key in the hash are called Symbol is a structure in Ruby. They're primarily used either as hash keys or for referencing method names. They're immutable, and Only one copy of any symbol exists at a given time, so they save memory.

You can convert a string or symbol with .to_sym or a symbol to string with .to_s to illustrate this let me show this example:

strings = ["HTML", "CSS", "JavaScript", "Python", "Ruby"]
symbolArray = [:HTML, :CSS, :JavaScript, :Python, :Ruby]
# Add your code below!

symbols = Array.new
strings.each {|x|
 symbols.push(x.to_sym)
}

string = Array.new
symbolArray .each {|x|
 string.push(x.to_s)
}
print symbols
print string

the result would be:

[:HTML, :CSS, :JavaScript, :Python, :Ruby]
["HTML", "CSS", "JavaScript", "Python", "Ruby"]

In ruby 9.1 you would see the symbols with the colons (:) in the right instead:

movies = { peter_pan: "magic dust", need_4_speed: "hey bro", back_to_the_future: "hey Doc!" }

I just wanted to make this point a litter more didactic so who ever is reading this can used.

One last thing, this is another way to solve your problem:

movie_ratings = {
  :memento =>  3,
  :primer => 3.5,
  :the_matrix => 3,

}
# Add your code below!

movie_ratings.each_key {|k| 
puts k.to_s
}

result:

memento
primer
the_matrix

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.