2016-04-01 52 views
1

我正在掃描滿足條件的source中的元素。條件通常但不總是正則表達式匹配。我正在尋找find的版本,該版本返回條件的結果,而不是原始元素。用find,我必須重新計算成功元素的標準。返回條件值的`find`,而不是元素值

我摸索出最好沿着這條線運行:

source.find {|e| if (m = e.match(/(e.)/)); break m[0]; end} 

爲了避免分號提示Rubocop抱怨多語句行,我喜歡寫如下:

source.find {|e| break m[0] if (m = e.match(/(e.)/))} 

但是Ruby無法應對前方參考(並且我沒有足夠扭轉以重新使用em)。

有沒有更優雅的做這項工作的捷徑?

+0

如果您不知道,您可以提出答案並選擇您認爲最有幫助的答案。 –

回答

1

既然你有break,你不需要find打破。使用each。如果正則表達式r

["dog", "cat", "emu", "pig"].find { |e| e =~ /(e.)/ } 
    #=> "emu" 
$1 
    #=> "em" 

(:

source.each {|e| m = e[/e./] and break m} 
+1

太過專注於'發現'和'注入'的聰明。謝謝。 –

0

雖然我更喜歡@sawa暗示什麼,你可以用一個實例變量:

["dog", "cat", "emu", "pig"].find { |e| $da_match = e[/(e.)/] } 
    #=> "emu" 
$da_match 
    #=> "em" 

,或者您正則表達式或者可能沒有)有一個外部捕獲組,你可以添加一個像這樣的:/(#{r})/。例如,

r0 = /e./ 
r1 = /(#{r0})/ 
    #/((?-mix:e.))/ 

["dog", "cat", "emu", "pig"].find { |e| e =~ r1 } 
    #=> "emu" 
$1 
    #=> "em" 

根據使用正則表達式的方式,這可能不起作用。如果(原始)正則表達式包含一個或多個捕獲組,則捕獲組1將成爲捕獲組2,依此類推。因此,如果在正則表達式或後續代碼中引用了其中一個捕獲組的內容,則會獲得錯誤的值。這不會是一個問題,但是,如果使用命名捕獲組和添加外一個保留的名稱:

["dog", "cat", "emu", "pig"].find { |e| e =~ /(?<outer>#{/e./})/ } 
    #=> "emu" 
$~[:outer] 
    #=> "em" 

$~是包含最近MatchData對象的全局變量。