【问题标题】:Ruby Enumerator "Single" methodRuby 枚举器“单一”方法
【发布时间】:2016-12-24 18:58:47
【问题描述】:

我真的需要使用类似于Single 方法的东西,它:

返回一个序列的唯一元素,如果序列中不完全是一个元素,则抛出异常。

显然,为了方便起见,我可以添加扩展/改进。

但是类似的东西已经存在了吗? 也许在 ActiveSupport 或其他库中?

【问题讨论】:

    标签: ruby monkeypatching enumerable refinements


    【解决方案1】:

    不,标准库中没有任何内容(我相信 ActiveSupport 也没有),但很容易实现。

    module EnumeratorWithSingle
      class TooManyValuesException < StandardError; end
      class NotEnoughValuesException < StandardError; end
    
      refine Enumerator do
        def single
          val = self.next
          begin
            self.next
            raise TooManyValuesException
          rescue StopIteration
            val
          end
        rescue StopIteration
          raise NotEnoughValuesException
        end
      end
    end
    
    module Test
      using EnumeratorWithSingle    
      puts [1].each.single            # 1
      puts [1, 2].each.single         # EnumeratorWithSingle::TooManyValuesException
    end
    

    【讨论】:

    • e = [1, 2].each; e.next; puts e.single 打印 2,这可能不是我们想要的结果。
    • 这是处理问题的好方法,但您的意思不是要把begin 作为single 的第一行吗?现在,如果self #=&gt; [].to_enumself.next 将引发一个不会被处理的StopIteration 异常。
    • @sreenslag 提出了一个有趣的观点。或许single的第一行应该是self_cpy = dup,然后对self.cpy进行操作。
    • @CarySwoveland:begin...enddef 级别是可选的。注意缩进。在每种情况下处理StopIteration(包括[].each.single);自己试试吧。
    • @steenslag:OP 明确要求提供Enumerator#single,而Enumerator 可能是可倒带的,也可能不是。因此,您实际上别无选择。对我来说,Enumerator#single 应该说“枚举器中只剩下一个值”。如果你想测试一个容器是否有一个值,它应该属于Enumerable#single,你知道self.each会给你整个序列。
    猜你喜欢
    • 2012-06-26
    • 2015-05-28
    • 1970-01-01
    • 2012-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-07
    • 1970-01-01
    相关资源
    最近更新 更多