我正在使用thetvdb.com API为一个节目获取插曲列表。一般来说,XML格式类似于:
<Data>
<Series>...</Series>
<Episode><EpisodeName>Foo</EpisodeName><EpisodeNumber>1</EpisodeNumber></Episode>
<Episode><EpisodeName>Bar</EpisodeName><EpisodeNumber>2</EpisodeNumber></Episode>
</Data>我所做的是使用Hash.from_xml解析XML,然后处理数据。为了迭代这些情节,我做了如下的事情:
hash_data['Data']['Episode'].each do ...这很好,如果有多个插曲。但是,如果只有一集,那么each方法实际上会迭代单个特定集的哈希条目,而不是只运行一次each方法。它破坏了我所有的代码。
我试过:
hash_data['Data']['Episode'].to_a.each do ...结果是一样的。一定有一种“正确”的方法来做这件事?
更新:--我认为这个问题很清楚,但似乎人们对此感到困惑。为了澄清这一点,我真的只是想反复看一遍剧集和内容。数据最初是以XML的形式接收的,因此为了在Ruby中检查数据,我使用Hash.from_xml(xml_response)将其转换为散列。
在“预期行为”方面,以以下例子为例:
hash_data['Data']['Episode'].each do |e| { puts e['EpisodeNumber'] }我预计,鉴于这一初步数据:
<Data>
<Series>...</Series>
<Episode><EpisodeName>Foo</EpisodeName><EpisodeNumber>1</EpisodeNumber></Episode>
<Episode><EpisodeName>Bar</EpisodeName><EpisodeNumber>2</EpisodeNumber></Episode>
</Data>产出如下:
1
2这是可行的。但是,如果给我这样的输入:
<Data>
<Series>...</Series>
<Episode><EpisodeName>Foo</EpisodeName><EpisodeNumber>1</EpisodeNumber></Episode>
</Data>我会崩溃,因为e['EpisodeNumber']是无效的。这是无效的,因为在只有一集的情况下,each实际上遍历哈希的每个键(因此进入each块的第一个值是EpisodeName的键值对),而不是像有多个元素时那样是一个散列数组。
换句话说,当有多集时,hash_data['Data']['Episode']是Hash类型的Array。当只有一集时,它只是一个Hash。如果有一个插曲,它仍然是一个Array,但其中只有一个项目,我的代码就能正常工作。但事实并非如此。我怎样才能妥善处理这件事?
我希望这能把它弄清楚?
更新2:有人要求我为返回的数据发布Hash#inspect。这是一部只有一集的节目:
{"Data"=>{"Series"=>{"id"=>"263752", "Actors"=>"||", "Airs_DayOfWeek"=>"Thursday", "Airs_Time"=>"10pm", "ContentRating"=>nil, "FirstAired"=>"2013-01-17", "Genre"=>"|Game Show|Reality|", "IMDB_ID"=>"tt2401129", "Language"=>"en", "Network"=>"TBS Superstation", "NetworkID"=>nil, "Overview"=>"Hosted by Robert Carradine and Curtis Armstrong, King of the Nerds is the ultimate nerd-off. The series will follow eleven fierce competitors from across the nerd spectrum as they set out to win $100,000 and be crowned the greatest nerd of them all.\n\nKing of the Nerds will take the glory of geekdom to a whole new level as the eleven competitors live together in \"Nerdvana.\" Each week, they must face challenges that will test their intellect, ingenuity, skills and pop culture prowess. In each episode, the nerds will first compete as teams and then as individuals, facing challenges that range from live gaming to a dance-off to life-sized chess. One competitor will be eliminated each week until one nerd stands alone as the ultimate champion off all things nerdy.", "Rating"=>nil, "RatingCount"=>"0", "Runtime"=>"60", "SeriesID"=>nil, "SeriesName"=>"King of the Nerds", "Status"=>"Continuing", "added"=>"2012-10-31 21:53:29", "addedBy"=>"348252", "banner"=>"graphical/263752-g2.jpg", "fanart"=>"fanart/original/263752-1.jpg", "lastupdated"=>"1357501598", "poster"=>nil, "zap2it_id"=>nil}, "Episode"=>{"id"=>"4428487", "Combined_episodenumber"=>"1", "Combined_season"=>"1", "DVD_chapter"=>nil, "DVD_discid"=>nil, "DVD_episodenumber"=>nil, "DVD_season"=>nil, "Director"=>nil, "EpImgFlag"=>nil, "EpisodeName"=>"Welcome to the Nerdvana", "EpisodeNumber"=>"1", "FirstAired"=>"2013-01-17", "GuestStars"=>nil, "IMDB_ID"=>nil, "Language"=>"en", "Overview"=>nil, "ProductionCode"=>nil, "Rating"=>nil, "RatingCount"=>"0", "SeasonNumber"=>"1", "Writer"=>nil, "absolute_number"=>nil, "filename"=>nil, "lastupdated"=>"1357501766", "seasonid"=>"504427", "seriesid"=>"263752"}}}注意,Episode是Hash类型。
这是一个有不止一集的节目:
{"Data"=>{"Series"=>{"id"=>"220441", "Actors"=>"||", "Airs_DayOfWeek"=>"Saturday", "Airs_Time"=>"8:30PM", "ContentRating"=>"TV-PG", "FirstAired"=>"2010-12-25", "Genre"=>"|Children|Drama|", "IMDB_ID"=>"tt1765510", "Language"=>"en", "Network"=>"The Hub", "NetworkID"=>nil, "Overview"=>nil, "Rating"=>"7.0", "RatingCount"=>"1", "Runtime"=>"30", "SeriesID"=>nil, "SeriesName"=>"R L Stine's The Haunting Hour", "Status"=>"Continuing", "added"=>"2011-01-10 15:59:43", "addedBy"=>"66501", "banner"=>"graphical/220441-g.jpg", "fanart"=>"fanart/original/220441-1.jpg", "lastupdated"=>"1354439519", "poster"=>"posters/220441-1.jpg", "zap2it_id"=>nil}, "Episode"=>[{"id"=>"3453441", "Combined_episodenumber"=>"1", "Combined_season"=>"1", "DVD_chapter"=>nil, "DVD_discid"=>nil, "DVD_episodenumber"=>nil, "DVD_season"=>nil, "Director"=>nil, "EpImgFlag"=>"2", "EpisodeName"=>"Really You (Part 1)", "EpisodeNumber"=>"1", "FirstAired"=>"2010-10-29", "GuestStars"=>"|Bailee Madison|Connor Price|", "IMDB_ID"=>nil, "Language"=>"en", "Overview"=>"A girl named Lilly (Bailee Madison) is given her very own life-sized \"Really You\" doll which is named Lilly D.; because she is good at manipulating her dad. Lilly remains a spoiled brat, bragging about Lilly D, even going as far as ripping the leg off a friends doll, after the friend informs Lilly that \"Lilly D hates Lilly\". Soon after, strange events begin to occur which Lilly's mother accuses Lilly of doing; despite how Lilly maintains she is innocent, and that Lilly D is alive.", "ProductionCode"=>nil, "Rating"=>"8.0", "RatingCount"=>"1", "SeasonNumber"=>"1", "Writer"=>nil, "absolute_number"=>nil, "filename"=>"episodes/220441/3453441.jpg", "lastupdated"=>"1350772755", "seasonid"=>"393441", "seriesid"=>"220441"}, ...注意,Episode现在是一个Hash类型的Array。
发布于 2013-01-10 20:53:55
听起来Rails的Array#wrap方法可以解决您的问题。我认为这样做是可行的:
Array.wrap(hash_data['Data']['Episode']).each do ...文档这里。
发布于 2013-01-10 19:12:13
使用哈希键/值方法
与Enumerator#each不同,您可能希望使用钥匙、价值或配对来迭代您的散列。
https://stackoverflow.com/questions/14265437
复制相似问题