【问题标题】:Hash key access via symbol not string [duplicate]通过符号而不是字符串访问哈希键[重复]
【发布时间】:2015-11-23 04:59:45
【问题描述】:

我有以下代码。我不明白为什么table['something']table[:something] 不同。

require 'json'
data = '[{"type":"local","db":"all","user":"postgres","addr":null,"method":"ident"},{"type":"local","db":"all","user":"all","addr":null,"method":"ident"},{"type":"host","db":"all","user":"all","addr":"0.0.0.0/0","method":"md5"},{"type":"host","db":"all","user":"all","addr":"::1/128","method":"md5"},{"type":"local","db":"communicator","user":"communicator","addr":" ","method":"trust"}]'
table = JSON.parse(data)
table.each do | auth |
  if (auth['user'])
    print( '\n\n\n' + auth[:user] )
  end
end

print( '\n\n\n' + auth[:user] ) 在线,我收到一个错误:

TypeError: no implicit conversion of nil into String
        from (irb):88:in `+'

这意味着通过:key 访问table'key' 不同。 为什么?如何转换 table 以使其与 :key 而不是 'key' 一起使用?

【问题讨论】:

  • 如果您制作downvote,请写下原因

标签: ruby


【解决方案1】:

符号 :key 不是字符串“键”,就像数字 3 不是字符串“3”一样。要将字符串转换为密钥,您可以使用 key.to_sym

关于其他两个 SO 问题之间的差异已被询问。 What's the difference between a string and a symbol in Ruby? 另见this文章

编辑 如果您无法控制源,则可以将键更改为符号的解决方案

require 'json'

data = '[{"type":"local","db":"all","user":"postgres","addr":null,"method":"ident"},{"type":"local","db":"all","user":"all","addr":null,"method":"ident"},{"type":"host","db":"all","user":"all","addr":"0.0.0.0/0","method":"md5"},{"type":"host","db":"all","user":"all","addr":"::1/128","method":"md5"},{"type":"local","db":"communicator","user":"communicator","addr":" ","method":"trust"}]'

table = JSON.parse(data)

p table
# [{"type"=>"local", "db"=>"all", "user"=>"postgres", "addr"=>nil, "method"=>"ident"}, {"type"=>"local", "db"=>"all", "user"=>"all", "addr"=>nil, "method"=>"ident"}, {"type"=>"host", "db"=>"all", "user"=>"all", "addr"=>"0.0.0.0/0", "method"=>"md5"}, {"type"=>"host", "db"=>"all", "user"=>"all", "addr"=>"::1/128", "method"=>"md5"}, {"type"=>"local", "db"=>"communicator", "user"=>"communicator", "addr"=>" ", "method"=>"trust"}]

table.map!{|auth| 
  new_auth = {}
  auth.each{|k, v| new_auth[k.to_sym] = v}
  new_auth
}

p table
# [{:type=>"local", :db=>"all", :user=>"postgres", :addr=>nil, :method=>"ident"}, {:type=>"local", :db=>"all", :user=>"all", :addr=>nil, :method=>"ident"}, {:type=>"host", :db=>"all", :user=>"all", :addr=>"0.0.0.0/0", :method=>"md5"}, {:type=>"host", :db=>"all", :user=>"all", :addr=>"::1/128", :method=>"md5"}, {:type=>"local", :db=>"communicator", :user=>"communicator", :addr=>" ", :method=>"trust"}]

【讨论】:

  • 如何转换我的表格以使其与 :key 而不是 'key' 一起使用?
  • 只需更改 print('\n\n\n' + auth['user']) 中的打印行
  • 我需要将基于字符串的 hast 转换为基于符号的...请理解我的问题
  • 像 {user: "postgres", ..} 改变你的源或者转换数组之后,我会发布一个例子
  • 被叫走了,如果您无法控制源,我发布了我提出的解决方案
【解决方案2】:

问题在于,{"user":"postgres"} 在 JSON 中的意思是:

{"user" => "postgres"}

在 Ruby 中,而在 Ruby 中则意味着:

{:user => "postgres"}

由于您将其作为 JSON 格式,因此您需要按以下方式访问该值:

auth["user"]

而不是:

auth[:user]

这是nil,因为哈希缺少密钥:user

【讨论】:

    【解决方案3】:

    因为'key'String:keySymbol - 这在Ruby 中是两个不同的东西。

    这可能有点令人困惑,因为:'key''key': 也将是Symbol 要使其正常工作,只需使用Symbol 访问Hash 字段,例如:

    if (auth[:user])
    

    要将 String indexed Hash 转换为 Symbol indexed Hash,请参考这个问题:

    Best way to convert strings to symbols in hash

    【讨论】:

    • 如何转换我的表格以使其与 :key 而不是 'key' 一起使用?
    • @WBAR,编辑了答案。
    • 我需要将基于字符串的 hast 转换为基于符号的...请理解我的问题
    • @WBAR,这是一个重复的比。
    • 最好的办法其实是设置:symbolize_names
    猜你喜欢
    • 2018-05-26
    • 1970-01-01
    • 2014-06-19
    • 1970-01-01
    • 2014-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-04
    相关资源
    最近更新 更多