a, b, c = 0, 1, 2
[a, b, c].find(&:zero?) # => 0
是否有任何方法可以找到塊返回false的第一個元素?在Ruby中有沒有與find相反的方法?
[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的第一個元素?在Ruby中有沒有與find相反的方法?
[a, b, c].the_method(&:zero?) # => 1
換句話說,它會表現方法一樣:據我所知還沒有做到這一點的一種標準方法
[a, b, c].reject(&:zero?).first
有is not,但你可以創建一個既乾淨上下的方式:
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
贏取黑客方式! =) – Aleksey 2017-02-03 14:29:28
(因爲find_all並拒絕相互借鑑,但是find沒有引用任何東西)。如果你需要頻繁(尤其是如果拒絕太慢),您可以編寫自己的
module Enumerable
def first_reject(&block)
find {|a| not (block.call(a)) }
end
end
但是,我同意Phrogz的觀點,只是寫出函數通常是最好的。 – 2011-04-29 22:13:25
如果你使用Ruby 2.0,你可以做lazy.reject(&:zero?).first
沒有經過去的性能損失整個陣列。
'拒絕(...)。第一個'看起來像你之後 - 這是什麼問題? – 2011-04-29 19:38:28
怎麼樣使用_Proc_? '[a,b,c] .find {| i | i!= 0}' – konus 2011-04-29 19:45:43
@Joe問題是你循環整個集合並創建一個完整的所有匹配值的數組,然後全部拋出。 'find'的美妙之處在於它一找到第一個匹配的值就停止迭代。 – Phrogz 2011-04-29 20:03:18