【问题标题】:Ruby each loop isn't finishing for each elementRuby 每个循环都没有为每个元素完成
【发布时间】:2011-06-14 06:50:02
【问题描述】:

以下代码:

# 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:等等等等……别告诉我!播客你应该知道的东西 怪胎经济学 RadioNPR:新鲜空气播客 NPR:汽车谈话播客 WNYC 的 Radiolab 卑鄙的我 猪动画卡通之前的珍珠飞蛾播客 APM:Wobegon 湖的草原家庭伴侣新闻哈利波特 1-5 年播客王牌在 HouseTakers - Takers Featurette:执行抢劫 - 制作接受者 NPR:Planet Money Podcast 你在历史课上错过的东西戴夫拉姆齐秀书评全球新闻吸血鬼 Suck ClipsNPR:科学星期五播客其他人崩溃和烧伤回到工作 NPR:所有歌曲都考虑播客 NPR:小桌音乐会播客 http://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://itun es.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-同伴/id215352157?uo=2&uo=2http://itunes.apple.com/us/podcast/harry-potter-years-1-5-podcast/id322144752?uo=2&uo=2http://itunes.apple.com/ us/podcast/ace-on-the-house/id414294132?uo=2&uo=2http://itunes.apple.com/us/podcast/takers-takers-featurette-executing/id412910974?uo=2&uo=2http:// itunes.apple.com/us/podcast/npr-planet-money-podcast/id290783428?uo=2&uo=2http://itunes.apple.com/us/podcast/stuff-you-missed-in-history/i d283605519?uo=2&uo=2http://itunes.apple.com/us/podcast/the-dave-ramsey-show/id77001367?uo=2&uo=2http://itunes.apple.com/us/podcast/book-评论/id120315179?uo=2&uo=2http://itunes.apple.com/us/podcast/global-news/id135067274?uo=2&uo=2http://itunes.apple.com/us/podcast/vampires-suck-剪辑/id405404825?uo=2&uo=2http://itunes.apple.com/us/podcast/npr-science-friday-podcast/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-songs-considered-podcast/id79687345?uo=2&uo=2http://itunes.apple.com/us/podcast/npr-tiny-desk-concerts-podcast/id362115318?uo= 2&uo=2

您可以看到它在继续访问 url 之前获取了所有元素的名称。我希望它先评估每个元素的名称,然后再评估 url 等,然后再继续下一个。我做错了什么。

谢谢。

【问题讨论】:

  • 你想让它对每一个做什么?
  • @Phrogz:我想他想打印类似“{name} {url} {name} {url}”而不是“{name} {name} ... {name} {网址} {网址} ... {网址}“
  • @Anon - 是的,就是这样。
  • 听起来你应该发布你的视图代码。

标签: ruby loops iteration


【解决方案1】:

导致此问题的原因有很多。首先,当你在每个循环中使用 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 更改为 ./name 以便它只返回当前节点。我还将每个更改为映射,以便将变量分配给包含块返回的所有值的数组。我删除了 return 的调用,因为它没有必要。

所以这将产生一个包含名称和 url 的数组数组

【讨论】:

  • 非常感谢。这是完美的,你的解释很有教育意义。
  • 您可能会更改您接受的答案以将 XML 解析为 XML 而不是 HTML。
【解决方案2】:

通过调用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"}]

【讨论】:

    【解决方案3】:

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

    试试return name + url + category + thing1 + thing2

    更好

    return [url,category,thing1,thing2]

    【讨论】:

    • 正确,但与提出的问题无关。
    猜你喜欢
    • 2017-12-05
    • 2022-01-21
    • 2014-08-15
    • 2020-10-21
    • 1970-01-01
    • 2020-03-09
    • 2015-06-01
    • 2020-10-03
    • 1970-01-01
    相关资源
    最近更新 更多