如何通过ruby中的变量访问冒号哈希键

时间:2014-08-27 22:28:29

标签: ruby hash

我有一个哈希数组,我想写一个通用检查器,所以我想传入要检查的键的名称。散列是使用带冒号前缀(符号)的键定义的。我无法弄清楚如何正确使用变量作为键。即使密钥存在于散列中,使用变量访问它也会导致nil。如何通过变量访问哈希键?也许另一种问题是,我如何将变量强制转换为符号?

在IRB中,我这样做:

>> 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
>>

5 个答案:

答案 0 :(得分:21)

您希望首先将字符串转换为符号:

another_family[somevar.to_sym]

如果您不想担心散列是符号还是字符串,只需将其转换为符号键

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

答案 1 :(得分:3)

由于您的键是符号,因此请使用符号作为键。

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

答案 2 :(得分:1)

您可以使用Active Support gem访问with_indifferent_access方法:

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

答案 3 :(得分:0)

如果您将Rails与ActiveSupport一起使用,请确实使用 HashWithIndifferentAccess 来灵活地访问带有字符串或符号的哈希。

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

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

somevar = :husband
puts family[somevar]
#Homer

答案 4 :(得分:-1)

你在散列中看到变量键的东西叫做Symbol是Ruby中的一个结构。它们主要用作散列键或引用方法名称。它们是不可变的,并且在给定时间只存在任何符号的一个副本,因此它们可以节省内存。

您可以将带有.to_sym或符号的字符串或符号转换为带.to_s的字符串来说明这一点让我展示这个例子:

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

结果将是:

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

在ruby 9.1中,你会在右边看到带冒号(:)的符号:

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

我只是想让这一点变得更有说服力,所以谁能读到这个就可以了。

最后一件事,这是解决问题的另一种方法:

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

}
# Add your code below!

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

结果:

memento
primer
the_matrix