【问题标题】:Returning the value of a block over an Enumeration when not nil在非 nil 时通过枚举返回块的值
【发布时间】:2011-12-25 16:23:51
【问题描述】:

对于 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? 的东西,但返回导致块为真的值,而不是只返回真。

也欢迎我尝试做的其他方法。

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

result = my_strategies.find do |strategy|
    strategy.get_result
end

除了这向我返回了成功的策略,而不是它成功时返回的值。我不在乎哪种策略让我获得了价值,我只想知道价值是什么。

【问题讨论】:

    标签: ruby enumerable


    【解决方案1】:

    您的需求非常普遍,但不幸的是核心中没有这样的抽象。然而,Facets 的人很久以前就发现了这个差距并实施了Enumerable#find_yield(又名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
    

    【讨论】:

    • 是的。这是我发现自己实施的一种模式。我想知道的是是否已经在某个地方实现了这个;我想避免编写我自己的现有功能版本。
    • @Ed:不,没有这样的抽象,我将编辑答案以添加一些参考。
    【解决方案2】:

    执行此操作的另一种方法(不使用块):

    result = nil
    num = 0
    
    while result.nil?
      result = my_strategies[num].get_result
      num += 1
    end
    

    【讨论】:

      【解决方案3】:

      您可以使用Enumerable#find 遍历数组,直到获得结果:

      result = nil
      
      my_strategies.find do |strategy|
          result = strategy.get_result
      end
      

      【讨论】:

      • 其实,现在我偶然发现了Enumerable#find,这好多了!
      • 查看我的编辑。这给了我一些不同于我想要返回的东西,除非我误解了 find 的语义。
      • 我不确定,但我认为 OP 想要 get_result 的输出,而不是策略本身。
      • 哦,拍摄。出于某种原因,我误读了文档......在闭包中分配应该可以解决这个问题。
      猜你喜欢
      • 1970-01-01
      • 2015-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-22
      • 1970-01-01
      相关资源
      最近更新 更多