我似乎对Ruby Enumerable有一个奇怪的用例。我试图做以下事情:
result = my_strategies.some_method do |strategy|
strategy.get_result
end
方法 some_method 只是一个占位符,但却是此问题其余部分的基础。
可枚举的my_strategies包含从远程服务检索值的有序策略列表;更优选的策略是在不太优选的策略之前运行,
有时候更优选的策略会失败,因为单独重试不会纠正。在这种情况下,策略将返回nil。
我可以通过依赖每个块看到一种方法:
result = nil
my_strategies.each do |strategy|
result = strategy.get_result
if not r.nil?
break
end
end
这似乎不必要地吵闹。我想知道在我的第一个例子中是否有一种方法可以替代 some_method ;类似于.any?的东西,但返回导致块为真的值,而不是返回true。
我也欢迎对我想做的事情采取替代方法。
编辑:我最初问过这个问题,因为我尝试过这段代码:
result = my_strategies.find do |strategy|
strategy.get_result
end
除了这使我成功的策略,而不是它返回时返回的值。我不关心哪种策略让我有价值,我只想知道价值是什么。
答案 0 :(得分:7)
您的需求非常普遍,但不幸的是核心中没有这样的抽象。但是,Facets家伙很久以前发现了这一差距并实施了Enumerable#find_yield(a.k.a Enumerable#map_detect):
result = my_strategies.map_detect { |strategy| strategy.get_result }
或者简单地说:result = my_strategies.map_detect(&:get_result)
。 Ruby 2.0实现了懒惰的枚举(对于早期版本使用enumerable-lazy)所以现在我们可以写:
result = my_strategies.lazy.map(&:get_result).reject(&:nil?).first
答案 1 :(得分:1)
您可以使用Enumerable#find
遍历数组,直到获得结果:
result = nil
my_strategies.find do |strategy|
result = strategy.get_result
end
答案 2 :(得分:0)
另一种方法(不使用块):
result = nil
num = 0
while result.nil?
result = my_strategies[num].get_result
num += 1
end