如何在Ruby中使用变量访问符号哈希键

29

我有一个哈希数组需要编写通用的检查器,因此我想传入要检查的键的名称。该哈希是使用符号(冒号前缀)作为键定义的。我无法弄清如何正确地使用变量作为键。尽管键存在于哈希中,但使用变量访问它会导致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
>>

我如何通过变量访问哈希键?或者说,我如何将变量强制转换为符号?


1
"husband".to_sym => :husband。 - Cary Swoveland
@CarySwoveland 当变量为nil时,要注意NoMethodError: undefined method `to_sym' for nil:NilClass。 - Ken Ratanachai S.
5个回答

49

请注意一些变量是否为nil。 - Ken Ratanachai S.

7
您可以使用 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"

1
这里使用了ActiveSupport核心扩展,这是选择特定扩展的正确方式。 - the Tin Man

3

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

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

这在某些情况下可能有效,但在我的情况下,我将它们作为参数传递,并且 Trollop(参数解析 gem)不会接受符号作为默认值。 - Leonard

0
如果您使用ActiveSupport的Rails,则应使用HashWithIndifferentAccess以便在访问哈希时具有字符串或符号的灵活性。
family = HashWithIndifferentAccess.new({
  'husband' => "Homer", 
  'wife' => "Marge"
})

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

somevar = :husband
puts family[somevar]
#Homer

-1

在 Ruby 中,哈希表中的变量键被称为符号(Symbol)结构。它们主要用于作为哈希表的键或引用方法名。它们是不可变的,并且在任何给定时间只存在一个符号的副本,因此可以节省内存。

您可以使用 .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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接