【问题标题】:How to access a symbol hash key using a variable in Ruby如何在 Ruby 中使用变量访问符号哈希键
【发布时间】:2014-10-21 16:11:11
【问题描述】:

我有一个哈希数组来编写一个通用检查器,所以我想传入一个要检查的键的名称。散列是用带有符号(冒号前缀)的键定义的。我不知道如何正确使用变量作为键。即使密钥存在于哈希中,使用变量访问它也会导致 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
>>

如何通过变量访问哈希键?也许另一种方式是问,我如何将变量强制转换为符号?

【问题讨论】:

  • "husband".to_sym => :husband.
  • @CarySwoveland 注意 NoMethodError: undefined method `to_sym' for nil:NilClass when var is nil

标签: ruby hash


【解决方案1】:

您想先将字符串转换为符号:

another_family[somevar.to_sym]

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

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

【讨论】:

  • 不过,请注意 nil somevar。
【解决方案2】:

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

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

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

【讨论】:

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

您在哈希中看到的变量键称为 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

【讨论】:

    【解决方案5】:

    如果您将 Rails 与 ActiveSupport 一起使用,请务必使用 HashWithIndifferentAccess 以灵活地使用字符串或符号访问哈希。

    family = HashWithIndifferentAccess.new({
      'husband' => "Homer", 
      'wife' => "Marge"
    })
    
    somevar = "husband"
    puts family[somevar]
    #Homer
    
    somevar = :husband
    puts family[somevar]
    #Homer
    

    【讨论】:

      猜你喜欢
      • 2013-04-18
      • 2014-04-16
      • 1970-01-01
      • 2011-10-31
      • 2012-01-01
      • 2014-04-09
      • 1970-01-01
      • 2012-02-06
      相关资源
      最近更新 更多