2016-04-01 2 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.)/))} 

しかし、ルビー前方参照に対処することができません(そして、私はのために十分に撚られていないのでeを再利用します)。

ショートカッティングでこの仕事をするのにもっとエレガントなものがありますか?

+0

知らなかった場合は、回答をアップアップするだけでなく、最も役立つ回答を選択することもできます。 –

答えて

1

breakを持っているため、findを壊す必要はありません。 eachを使用してください。正規表現rがない場合(

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

:あなたの正規表現のために、

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

か:私は@sawaが示唆するものを好むものの

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

「発見」と「インジェクト」の巧みさに夢中です。ありがとう。 –

0

、あなたはインスタンス変数を使用することができますまたはそうでないかもしれません)、外側のキャプチャグループを持っている場合は、/(#{r})/のように1つ追加できます。たとえば、

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

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

正規表現の使用方法によっては、これが機能しない場合があります。 (元の)正規表現に1つまたは複数のキャプチャグループが含まれている場合、キャプチャグループ1はキャプチャグループ2になります。したがって、これらのキャプチャグループの1つの内容が正規表現内または後続のコード内で参照されると、不正な値が取得されます。名前付きキャプチャグループを使用して、コメントを追加している外側のいずれかの名前を予約した場合、これは問題ではないでしょう、しかし、:

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

$~最新MatchDataオブジェクトを含むグローバル変数です。

関連する問題