在 ruby 中跳过yield块的迭代
尝试使用一个构思不良的框架,该框架从传入的块中收集结果列表,实际上是这样的:
def sigh(&block)
r = (1..3).collect do |i|
yield(i)
end
# do something with r
end
我希望传入的块来过滤项目,但要跳过集合迭代而不是像 next
那样将 nil
添加到结果中(因为框架不会压缩它们。)除了修补 gem 之外,还有什么简单的方法呢? IE,
sigh {|i| next unless i == 1 } # results in [1,nil,nil] rather than just [1]
Trying to use an ill-conceived framework which collects a list of results from a passed-in block, effectively this:
def sigh(&block)
r = (1..3).collect do |i|
yield(i)
end
# do something with r
end
I want the block I pass in to filter the items, but to skip the collection iteration rather than adding nil
to the results like next
would (since the framework doesn't compact them.) What's a simple way other than patching the gem? I.e.,
sigh {|i| next unless i == 1 } # results in [1,nil,nil] rather than just [1]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
坏消息是你必须修补 gem。让 gem 调用您的代码块并不会给您的代码带来任何特殊的权力来影响调用代码如何处理块的返回值。
好消息是,修补 gem 通常可以通过“猴子补丁”来完成,您的程序会重新打开 gem 的类或模块并进行更改。在这个虚构的示例中,我们将显示嵌套在模块中的类,因为许多 gems 使用嵌套类和模块:
The bad news is that you'll have to patch the gem. Having your code block called by the gem doesn't give your code any special powers to affect how the calling code processes the block's return values.
The good news is that patching the gem can usually be done with a "monkey patch," where your program reopens the gem's class or module and makes the change. In this made-up example, we'll show the class nested in a module, since many gems make use of nested classes and modules:
没有办法做到你所要求的。不过,如果您发布有关您正在使用的框架的更多详细信息,这里的某人可能可以帮助您想出一种不同的方法来解决该问题。
There is no way to do what you are asking for. If you post more details on the framework you are using, though, someone here may be able to help you think of a different way to work around the problem.
正如其他人所说,您需要修补。如果你想要一个满足某些条件的
i
集合,最好的选择是将collect
替换为find_all
,然后你可以使用:You'll need to patch, like others said. If you want a collection of
i
which satisfy some condition, the best choice would to replacecollect
withfind_all
, and then you could use: