我对ruby很新,习惯于JS和C#,处理嵌套块,我在这里有2个'循环',应该打印完全相同的东西。
page.search( "//div[@id='mw-content-text']" ).search("p").find do |p|
puts p.inner_text.gsub(/[^a-z ]/i, '').split( ' ' )
end
page.search( "//div[@id='mw-content-text']" ).search("p").find do |p|
p.inner_text.gsub(/[^a-z ]/i, '').split( ' ' ).each do |word|
puts word
end
end
他们都开始在页面中获取所有段落标记,然后迭代它们。第一个按预期运行,但是当我尝试使用嵌套块迭代每个单词时,我只从外部块获得一个结果。好像第一个“结束”正在破坏外部块或其他东西。 这是正常的红宝石行为吗?我错过了一些明显的东西吗?
感谢您的帮助。
西蒙。
答案 0 :(得分:1)
如果要遍历所有p元素,可能需要使用each
而不是find
。 find
方法“将枚举中的每个条目传递给块。返回第一个块不是false的。”
答案 1 :(得分:1)
在Ruby中,每个方法调用或块都返回它返回的最后一行代码行(或者如果它为空则为nil)。除非您希望过早地停止执行,否则不需要显式调用return(以及无论如何都不能调用它的块)。现在记住这一点,我们可以测试puts("something").nil? #=> true
。在条件语句中,nil被认为是假的,这就是为什么第一次调用find会遍历整个集合。对于每个p标签,您只需调用puts返回nil并告诉我发现这不是我们正在寻找的元素。但是,每个方法返回它所调用的任何内容(因此你可以链接调用),如[].each {}.class #=> Array
所示,从而向find方法指示找到了你正在寻找的任何东西,我们可以停止迭代该集合。最后,find方法返回搜索结果中的第一个p元素。
答案 2 :(得分:1)
page.search( "//div[@id='mw-content-text']" ).search("p")
获得Enumerable。
将枚举中的每个条目传递给阻止。返回第一个块不为false的块。如果没有对象匹配,则调用ifnone并在指定时返回其结果,否则返回nil。 实施例。
(1..10).find {|item| p item}
# 1.
您可以使用Enumerable#find_all,Enumerable#collect,地图
实施例
(1..10).find_all {|item| p item}
# 1 2 3 4 ... 10
[1,2,3,4,5,6,7,8,9,10]
希望它可以帮助你。