a, b, c = 0, 1, 2
[a, b, c].find(&:zero?) # => 0
ブロックがfalseを返す最初の要素を見つけるメソッドはありますか?
[a, b, c].the_method(&:zero?) # => 1
つまり、次のように動作します。
[a, b, c].reject(&:zero?).first
a, b, c = 0, 1, 2
[a, b, c].find(&:zero?) # => 0
ブロックがfalseを返す最初の要素を見つけるメソッドはありますか?
[a, b, c].the_method(&:zero?) # => 1
つまり、次のように動作します。
[a, b, c].reject(&:zero?).first
はありませんが、きれいな方法で作成できます。
a = [0,2,1,0,3]
module Enumerable
def first_not(&block)
find{ |x| !block[x] }
end
end
p a.first_not(&:zero?)
#=> 2
...または恐ろしく面白いハック方法:
class Proc
def !
proc{ |o,*a| !self[o,*a] }
end
end
p a.find(&!(:zero?.to_proc))
#=> 2
...または、簡潔だが非常に危険な方法:
class Symbol
def !
proc{ |o,*a| !o.send(self,*a) }
end
end
p a.find(&!:zero?)
#=> 2
しかし、トリッキーな使用法をスキップして、Symbol#to_proc
あなたが望むことを言うことをお勧めします:
p a.find{ |i| !i.zero? }
#=> 2
lazy.reject(&:zero?).first
Ruby 2.0 を使用している場合は、配列全体を処理することによるパフォーマンスの低下を回避できる場合があります。
私が知る限り、これを行うための標準的な方法はありません (find_all と reject が相互に参照しているが、find は何も参照していないとします)。頻繁に必要な場合 (特に拒否が遅すぎる場合) は、独自の
module Enumerable
def first_reject(&block)
find {|a| not (block.call(a)) }
end
end