当不是nil时,在Enumeration上返回块的值

Ed *_*rel 2 ruby enumerable

看来,我对Ruby Enumerable有一个奇怪的用例.我试图做类似以下的事情:

result = my_strategies.some_method do |strategy|
    strategy.get_result
end
Run Code Online (Sandbox Code Playgroud)

该方法some_method只是一个占位符,但这个问题的人的后面的基础.

可枚举的my_strategies包含用于从远程服务检索值的有序策略列表; 更优选的策略是在不太优选的策略之前运行,

有时候更优选的策略会失败,因为单独重试不会纠正.在这种情况下,策略将返回零.

我可以通过依赖每个块来看到这样做的方式,因此:

result = nil

my_strategies.each do |strategy|
    result = strategy.get_result
    if not r.nil?
        break
    end
end
Run Code Online (Sandbox Code Playgroud)

这似乎不必要地嘈杂.我想知道在我的第一个例子中是否有一种方法可以替代some_method ; 类似于.any?的东西,但是返回导致块为真的值,而不是返回true.

我也欢迎采用替代方法来实现我的目标.

编辑:我最初问这个问题,因为我尝试过这段代码:

result = my_strategies.find do |strategy|
    strategy.get_result
end
Run Code Online (Sandbox Code Playgroud)

除了这使我成功的策略,而不是它返回时返回的值.我不关心哪种策略让我有价值,我只想知道价值是什么.

tok*_*and 7

您的需求非常普遍,但遗憾的是核心中没有这样的抽象.然而,Facets的人很久以前发现了这个差距并实现了Enumerable#find_yield(又名Enumerable#map_detect):

result = my_strategies.map_detect { |strategy| strategy.get_result }
Run Code Online (Sandbox Code Playgroud)

或者简单地说:result = my_strategies.map_detect(&:get_result).Ruby 2.0实现了懒惰的枚举(对于早期版本使用enumerable-lazy)所以现在我们可以编写:

result = my_strategies.lazy.map(&:get_result).reject(&:nil?).first
Run Code Online (Sandbox Code Playgroud)