🍣

Grow.rbのpredicates問題を解いてみる

2024/12/31に公開

Grow.rbとは:

Ruby力を高めたいRubyistたちが、コードを書いたりちょっとマニアックな内容を学んだりするコミュニティです。

以下のRubyメソッドをRubyで作ってみようというテーマです。

  • all?
  • any?
  • include?
  • one?
  • none?

テストコードはこちら。

https://github.com/grow-rb/enumerable-exercises/blob/d08568e5319c9d24a74c9cb635ed1115ad43adc3/predicates/predicates_test.rb#L1-L60

書いた回答がこちら。eachのみを使う縛り。

module Enumerable
  def my_all?(arg = nil)
    each do |el|
      if arg
        return false unless arg === el
      elsif block_given?
        return false unless yield(el)
      else
        return false unless el
      end
    end
    return true
  end

  def my_any?(arg = nil)
    each do |el|
      if arg
        return true if arg === el
      elsif block_given?
        return true if yield(el)
      else
        return true if el
      end
    end
    return false
  end

  def my_include?(arg)
    each do |el|
      return true if arg == el
    end
    return false
  end

  def my_one?(arg = nil)
    count = 0
    each do |el|
      if arg
        count += 1 if arg === el
      elsif block_given?
        count += 1 if yield(el)
      else
        count += 1 if el
      end
      return false if count > 1
    end

    return true if count == 1
  end

  def my_none?(arg = nil)
    count = 0
    each do |el|
      if arg
        count += 1 if arg === el
      elsif block_given?
        count += 1 if yield(el)
      else
        count += 1 if el
      end
      return false unless count.zero?
    end

    return true if count.zero?
  end
end

Rubyでは明示的にreturnを書くとRubocopに指摘されるけど、個人的には明示的に書きたい派。「あ、ここで値が返されるんだな」とパッと見てわかる。

Discussion