Ruby的每个循环都没有为每个元素完成

时间:2011-01-24 03:39:06

标签: ruby loops iteration

以下代码:

# fetch the top 300 podcasts from itunes
itunes_top_300 = Nokogiri.HTML(open("http://itunes.apple.com/us/rss/toppodcasts/limit=25/xml"))

# parse the returned xml with nokogiri
itunes_top_300.xpath('//feed/entry').each do |entry|
  name = entry.xpath("//name").text
  url = entry.xpath("//link/@href").text
  category = entry.xpath("//category/@term").text
  hosts = entry.xpath("//artist").text
  summary = entry.xpath("//summary").text
  artwork = entry.xpath("//image[@height='170']").text
  return name + url
end

在视图中输出:

  

iTunes StoreThis American LifeNPR:等等......不要告诉我! PodcastStuff你应该知道神经系统RadioNPR:新鲜播客NPR播客:汽车谈话播客WNYC的Radiolab可爱的MePearls之前的动画片动画片The Moth PodcastAPM:来自Lake Wobegon的草原家庭同伴的新闻Harry Potter岁月1-5播客关于HouseTakers - Takers Featurette:执行抢劫 - 制作TakersNPR:Planet Money PodcastStuff你错过了历史课Dave Ramsey ShowBook评论全球新闻吸血鬼Suck ClipsNPR:Science Friday Podcast其他人崩溃和BurnBack到WorkNPR:所有歌曲被认为是PodcastNPR:Tiny Desk音乐会Podcasthttp://itunes.apple.com/WebObjects/MZStore。 WOA / WA / viewTop ID = 38&安培; popId = 3http:?//ax.itunes.apple.com/WebObjects/MZStoreServices.woa/ws/RSS/toppodcasts/limit=25/xml CC = ushttp://的iTunes。 apple.com/us/podcast/this-american-life/id201671138?uo=2&uo=2http://itunes.apple.com/us/podcast/npr-wait-wait-dont-tell-me/id121493804? UO = 2及UO = 2http://itunes.apple.com/us/podcast/stuff-you-should-know/id278981407 UO = 2及; UO = 2http://itunes.apple.com/us/podcast/freakonomics-radio/id354668519 UO = 2及UO = 2http://itunes.apple.com/us/podcast/npr-fresh-air-podcast /id214089682?uo=2&uo=2http://itunes.apple.com/us/podcast/npr-car-talk-podcast/id253191823?uo=2&uo=2http://itunes.apple.com/us /podcast/wnycs-radiolab/id152249110?uo=2&uo=2http://itunes.apple.com/us/podcast/despicable-me/id399247154?uo=2&uo=2http://itunes.apple.com /us/podcast/pearls-before-swine-animated/id409382502?uo=2&uo=2http://itunes.apple.com/us/podcast/the-moth-podcast/id275699983?uo=2&uo=2http ?://itunes.apple.com/us/podcast/apm-a-prairie-home-companions/id215352157 UO = 2及UO = 2http://itunes.apple.com/us/podcast/harry-potter-years -1-5-播客/ id322144752 UO = 2及UO = 2http://itunes.apple.com/us/podcast/ace-on-the-house/id414294132 UO = 2及UO = 2http://的iTunes .apple.com / US /播客/接受者 - 接受-特辑-执行/ id412910974 UO = 2及UO = 2http:?//itunes.apple.com/us/podcast/npr-planet-money-podcast/id290783428 UO = 2及UO = 2 http://itunes.apple.com/us/podcast/stuff-you-missed-in-history/id283605519?uo=2&uo=2http://itunes.apple.com/us/podcast/the-dave-拉姆齐 - 显示/ id77001367 UO = 2及UO = 2http://itunes.apple.com/us/podcast/book-review/id120315179 UO = 2及UO = 2http://itunes.apple.com/us/播客/全球新闻/ id135067274 UO = 2及UO = 2http://itunes.apple.com/us/podcast/vampires-suck-clips/id405404825 UO = 2及UO = 2http://itunes.apple。 COM /美国/播客/ NPR-科学周五 - 播客/ id73329284 UO = 2及UO = 2http:??//itunes.apple.com/us/podcast/other-guys-crash-and-burn/id407622041 UO = 2及UO = 2http://itunes.apple.com/us/podcast/back-to-work/id415535037 UO = 2及UO = 2http://itunes.apple.com/us/podcast/npr-all-歌曲考虑的播客/ id79687345 UO = 2及UO = 2http:?//itunes.apple.com/us/podcast/npr-tiny-desk-concerts-podcast/id362115318 UO = 2及UO = 2

在进入url之前,您可以看到它正在获取所有元素的名称。我想让它为每个元素评估name然后是url等,然后再继续下一个元素。我做错了什么。

感谢。

3 个答案:

答案 0 :(得分:2)

导致此问题的原因有很多。首先,当你在每个循环中使用return时,你实际上是在打破它,所以它只迭代一次,而不是25次。

其次,您可能没有注意到它只运行一次,因为当您在xpath中使用// name时它将返回所有名称。

也许你可以做这样的事情:

# Returns top 25 since the url includes limit=25
itunes_top_25 = Nokogiri.XML(open("http://itunes.apple.com/us/rss/toppodcasts/limit=25/xml"))

names_and_urls = itunes_top_25.xpath('//feed/entry').map do |entry|
  name = entry.xpath("./name").text
  url = entry.xpath("./link/@href").text
  category = entry.xpath("./category/@term").text
  hosts = entry.xpath("./artist").text
  summary = entry.xpath("./summary").text
  artwork = entry.xpath("./image[@height='170']").text
  [name, url]
end    

我将//名称更改为./name,以便它只返回当前节点。我还将每个更改为map,以便将变量分配给具有块返回的所有值的数组。我删除了要返回的电话,因为没有必要。

因此,这将导致包含名称和URL的数组数组

答案 1 :(得分:1)

通过调用return,您将在第一次迭代时停止each循环。可能你不想那样。此外,通过在循环中使用xpath //name,您将从文档的顶部开始并查找整个文档中的每个名称元素。因此,当您找到第一个<entry>时,您返回了一个数组,该数组是通过将文档中每个<name>元素的数组与文档中每个<url>元素的数组连接而形成的。

你可能想要这个:

require 'nokogiri'
require 'open-uri'
# fetch the top 300 podcasts from itunes
# Use XML instead of HTML
itunes_top_300 = Nokogiri::XML(open("http://itunes.apple.com/us/rss/toppodcasts/limit=25/xml"))
itunes_top_300.remove_namespaces!

itunes_top_300.xpath('//entry').each do |entry|
  name = entry.xpath("name").text
  url = entry.xpath("link/@href").text
  puts "#{name}: #{url}"
end
#=> This American Life: http://itunes.apple.com/us/podcast/this-american-life/id201671138?uo=2&uo=2
#=> NPR: Wait Wait... Don't Tell Me! Podcast: http://itunes.apple.com/us/podcast/npr-wait-wait-dont-tell-me/id121493804?uo=2&uo=2
#=> Stuff You Should Know: http://itunes.apple.com/us/podcast/stuff-you-should-know/id278981407?uo=2&uo=2

...或者也许这样:

# Convert XML entries into an array of hashes
parsed = itunes_top_300.xpath('//entry').map do |entry|
  name = entry.xpath("name").text
  url = entry.xpath("link/@href").text
  { name:name, url:url }
end

require 'pp'
pp parsed[0..3]
#=> [{:name=>"This American Life",
#=>   :url=>"http://itunes.apple.com/us/podcast/this-american-life/id201671138?uo=2&uo=2"},
#=>  {:name=>"NPR: Wait Wait... Don't Tell Me! Podcast",
#=>   :url=>"http://itunes.apple.com/us/podcast/npr-wait-wait-dont-tell-me/id121493804?uo=2&uo=2"},
#=>  {:name=>"Stuff You Should Know",
#=>   :url=>"http://itunes.apple.com/us/podcast/stuff-you-should-know/id278981407?uo=2&uo=2"},
#=>  {:name=>"Freakonomics Radio",
#=>   :url=>"http://itunes.apple.com/us/podcast/freakonomics-radio/id354668519?uo=2&uo=2"}]

答案 2 :(得分:0)

你用你想要的东西声明变量然后扔掉它,因为你只有return name + url

而是尝试return name + url + category + thing1 + thing2

更好

return [url,category,thing1,thing2]