我试图理解grep在这个例子中是如何工作的.代码有效,但我不是100%确定事件发生的顺序,或者我是否正确理解了何时何地返回的内容.
cars = [:Ford, :Toyota, :Audi, :Honda]
ucased_cars = cars.collect do |c|
c.to_s
end
.grep(/^Ford/) do |car|
puts car.upcase
car.upcase
end
puts "ucased:" + ucased_cars.to_s
Run Code Online (Sandbox Code Playgroud)
我认为发生的是:
就第4步而言,以下哪项最能说明grep的工作原理:
[A] grep查找与模式匹配的所有字符串.grep在这个匹配数组上调用块.grep将块的结果返回给调用函数.
[B] grep找到匹配模式的第一个字符串.grep在这场比赛中调用该块.这个区块的返回值暂时堆积在某个地方.grep搜索数组的下一个元素.如果匹配,grep会在此匹配上调用该块.grep将此块的返回值添加到返回值的临时"存储"中.grep查看下一个数组元素,直到找不到更多匹配项.然后grep将堆积的返回值传递回调用函数.
我的结论:
[A]似乎更有意义.
[B]似乎有很多不必要的捏造,似乎没有效率或可能性.
Ori*_*rds 12
首先,这是grep的文档
让我清理你的代码并逐一解释
# 1
cars = [:Ford, :Toyota, :Audi, :Honda]
# 2
ucased_cars = cars.collect do |c|
c.to_s
end.grep(/^Ford/) do |car| # 3
puts car.upcase # 4
car.upcase # 5
end
# 6
# 7
puts "ucased:" + ucased_cars.to_s
Run Code Online (Sandbox Code Playgroud)
声明符号数组
使用collect将符号转换为字符串.你得到["Ford", "Toyota", "Audi", "Honda"]
将这个字符串数组输入grep.任何与正则表达式匹配的项目都/^Ford/将被送入块中
该块打印出它所提供的上行字符串
该块返回upcased字符串,grep然后作为"匹配值"
从grep的返回值(这是所有的"匹配值"的数组)被分配到ucased_cars,这是["FORD"],因为这是匹配正则表达式的唯一事情.
然后打印出来.在to_s阵列上做一个只打印所有阻塞的元素.这不是很有用,你最好打印ucased_cars.inspect
回答你关于grep如何在幕后工作的问题......
上面的文档页面显示了grep本身的C源代码.它基本上是这样的:
rb_iterate遍历源代码中的每个元素,并传入一些特定于grep的代码.rb_iterate也使用collect,each_with_index和一堆其他的东西.由于我们知道collect/each/etc是如何工作的,我们不需要在源代码中进行任何更多的探索,我们有答案,而且它是你的[B].
为了更详细地解释,它这样做:
至于你对"A似乎更有意义"的评论 - 我不同意.
这个想法是块对每个元素做了一些事情.如果它首先扫描了源,然后将匹配数组传递给块,那么你的块就必须自己调用each,这很麻烦.
其次,效率会降低.例如,如果你的块调用return或引发错误会发生什么?在它的当前版本中,您可以避免扫描其余的源.如果它已经预先扫描了整个源列表,那么你就浪费了所有这些努力.
| 归档时间: |
|
| 查看次数: |
813 次 |
| 最近记录: |