【问题标题】:`[]': can't convert String into Integer (TypeError) Ruby`[]': 无法将字符串转换为整数 (TypeError) Ruby
【发布时间】:2013-01-22 23:14:52
【问题描述】:

我正在尝试遍历 JSON 解析哈希表(具有嵌套的哈希数组)并插入到 Text Table 中。我试图迭代的 JSON 解析代码是:

{"server"=>{"security_groups"=>[{"name"=>"default"}], "adminPass"=>"LhXEPMkYmqF7",   "id"=>"82b7e32b-f62b-4106-b499-e0046250229f", "links"=>[{"href"=>"http://10.30.1.49:8774/v2/89fc0b9d984d49fba5328766e923958f/servers/82b7e32b-f62b-4106-b499-e0046250229f", "rel"=>"self"}, {"href"=>"http://10.30.1.49:8774/89fc0b9d984d49fba5328766e923958f/servers/82b7e32b-f62b-4106-b499-e0046250229f", "rel"=>"bookmark"}], "OS-DCF:diskConfig"=>"MANUAL"}}

我用来迭代顶部的代码是:

server_table = Text::Table.new do | t |
      t.head = ['Server ID', 'Server URL', 'Admin Password']
   end
response = JSON.parse(r)

response['server'].each do | serv_info |
  server_table.rows << [["#{serv_info['id']}", "#{serv_info['links'][0]['href']}", "#{serv_info['adminPass']}"]]
end

puts server_table

我收到错误:

/lib/get_token.rb:166:in `[]': can't convert String into Integer (TypeError)
    from ./lib/get_token.rb:166:in `create_server'
    from ./lib/get_token.rb:165:in `each'
    from ./lib/get_token.rb:165:in `create_server'

如果我单独使用 puts 打印出每个命令,它们可以正常工作,但迭代不会。提取正确信息的命令是:

puts response['server']['links'][0]['href']
puts response['server']['id']
puts response['server']['adminPass']

所有这 3 个工作,但如果我尝试迭代它们,我会得到字符串错误。我知道这与 .each 返回一个哈希数组有关,但我不完全理解为什么 PUTS 命令在脚本和 IRB 中都没有问题。

有什么想法吗?

【问题讨论】:

  • 不要使用puts,而是尝试使用pp,这将输出数据的格式化版本。这是一种帮助可视化您的数据结构真正是什么的临时方法。 puts 可以通过添加一个你并不真正注意的额外换行来掩盖嵌套。
  • 很高兴知道,特别是因为我是新手 :) 谢谢伙计!

标签: ruby hash


【解决方案1】:

每个serv_info 都是一对映射,表示为一个由 2 个元素组成的数组。因此,代码中&lt;&lt; 之后的所有内容都是错误的。

避免此类错误的秘诀是停止尝试混淆您自己的代码。

server_table.rows 应该包含所有可能的三元组服务器 ID、链接和密码。

response = # { "server" => ...}
server = response['server']
server_id = server['id']
link_infos = server['links']
admin_pass = server['adminPass']

link_infos.each do |link_info|
  link = link_info['href']
  server_table.rows << [server_id, link, admin_pass]
end

更新

我们可以轻松地使用这段代码来处理多个服务器

response = # [ {"server" => ...}, ...]
response.each do |server|
   ... # above code snippet goes here 
       # or you may extract it into a method and call it here
end

另外我想提一下irb 非常适合处理这类问题。它是一个命令行 Ruby 解释器,非常适合原型设计。它会打印出您键入的每个语句的结果,并具有自动完成功能以帮助您找到所需的类/方法。无需等待几个小时才能获得简单问题的 SO 答案,您将在几分钟内使用 irb 得到它。

【讨论】:

  • 哈哈,谢谢。我是红宝石新手,只有两周时间,所以我真的很感激这个答案。我试图压缩我猜想的代码,但我知道这会让我在未来遇到严重的麻烦。你摇滚!
  • 下一个编码问题,我想看看我是否做对了。如果我得到一个我解析出的 JSON 响应,其中包含多个 ['server'] 条目(创建多个服务器),我会使用 pastebin.com/MP0RJy2K 迭代您的代码
  • @hoha - 我忘了添加这个作为通知
  • 你的 sn-p 有一个错误,在 json_response['server'].each 你有一个数组 json_resonse 并且数组不能用字符串键(如“服务器”)访问 - 你会得到一个错误。查看更新后的帖子。
  • 感谢大家的帮助,呵呵,非常感谢。
【解决方案2】:

也许你的意思只是

serv_info = response['server']
server_table.rows << [["#{serv_info['id']}", "#{serv_info['links'][0]['href']}",      "#{serv_info['adminPass']}"]]

因为response['server'] 是一个散列而不是一个数组。

【讨论】:

    【解决方案3】:

    而不是使用:

    server_table.rows << [["#{serv_info['id']}", "#{serv_info['links'][0]['href']}", "#{serv_info['adminPass']}"]]
    

    试试:

    server_table.rows += [["#{serv_info['id']}", "#{serv_info['links'][0]['href']}", "#{serv_info['adminPass']}"]]
    

    或者:

    server_table.rows << ["#{serv_info['id']}", "#{serv_info['links'][0]['href']}", "#{serv_info['adminPass']}"]
    

    【讨论】:

      猜你喜欢
      • 2013-12-18
      • 2015-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多