在Ruby中查询JSON嵌套哈希响应的问题

时间:2014-03-08 15:05:04

标签: ruby-on-rails ruby json hash nested

似乎无法解决这个问题:

我从Lastfm获取JSON嵌套哈希响应,当响应是这样的结构时,一切正常:

{"topalbums" =>{"album" =>{"name =>"Friday Night in Dixie"}}}

然而,如果艺术家没有顶级专辑,那么响应是以这种方式构建的,我得到一个NoMethodError未定义的方法'[]'为nil:NilClass。

{"topalbums" =>{"#text"=>"\n   ", "artist"=>"Mark Chestnutt"}}

我想要做的是查询响应,这样我就不会收到此错误。

这是我的方法:

 def get_albums
   @albums = Array.new
   @artistname.each do |name|
      s = LastFM::Artist.get_top_albums(:artist => name, :limit => 1)
      r = JSON.parse(s.to_json)['topalbums']['album']['name']
      @albums.push(r)
   end
 end

如果艺术家有一张顶级专辑,它给了我我想要的东西,我需要做的是以某种方式添加一个条件来查询嵌套散列中的键。但是,当我添加这行代码来检查键值时,我似乎无法掌握如何执行此操作:

s.each_key { |key, value| puts "#{key} is #{value}" } 

我得到的输出是:

  

topalbums是

所以topalbums键没有与之关联的值。

这是我到目前为止所尝试的:

  def get_albums
   @albums = Array.new
   @artistname.each do |name|
      s = LastFM::Artist.get_top_albums(:artist => name, :limit => 1)
      if s.has_key?('album') #I know this won't work but how can I query this?
         r = JSON.parse(s.to_json)['topalbums']['album']['name']
         @albums.push r 
      else
         @albums.push(name << "does not have a top album")
      end
   end
 end

我如何解决这个问题,因此我得到'Mark Chestnut没有顶级专辑'而不是NoMethodError?干杯

1 个答案:

答案 0 :(得分:4)

使用Hash#fetch默认值,我会按以下方式执行:

没有"album"密钥出现

hash = {"topalbums" =>{"#text"=>"\n   ", "artist"=>"Mark Chestnutt"}}
default_album = {"name" => "does not have a top album"}
hash["topalbums"].fetch("album", default_album)["name"]
#=> "does not have a top album"

"album"密钥出现

hash = {"topalbums" =>{"#text"=>"\n   ", "artist"=>"Mark Chestnutt", "album" => {"name" => "Foo"}}}
hash["topalbums"].fetch("album", default_album)["name"]
#=> "Foo"

因此,如果哈希没有"album"密钥fetch默认为default_album,那么它会使用它找到的密钥,如第二种情况