2017-08-23 7 views
0

私は計算コストの高い検索を持ち、かつ明白な理由のためではなく、オリジナルよりも計算値をしたい:Rubyでは、計算コストの高い検索で無限値を返すのに最適です。

%x(...).each_line.find { |l| m = l.match(/^(\S+).*System(.*)/) ; break m if m } 

each_lineにブロックを与えることが失敗した場合に、元の文字列を返すためfindが必要であると思われます。私はすべての一致した行のグループをしたい場合は

、私は私はそれが「ないRubyの道」ので、私はずselect前にI mapだ集める、map { ... }.compactことができますが。 (実際には許容可能なプラクティスと考えていることですか?)

私はeach_lineとそのアプローチを使用してみました、それは怠惰になっので、私は最後にfirstを求めることもできますが、私はできなかったcompactselect{|x|x}と書く必要がありました。

%x(...) 
    .each_line.lazy 
    .map { |l| l.match(/^(\S+).*System(.*)/) } 
    .select { |x| x } # lol, .compact pls. 
    .first 

もっとエレガントなものがありますか?


アップデート:私は

"foo\nbar".each_line.lazy.flat_map{ |l| l.match(/([ao])/) || [] }.first 

でつもりが、佳作がgrep基づいて回答するためのシンプルなライムに行きます。

答えて

0

、私は思う:

matches = %x(./script.rb).each_line.lazy.grep(/^(\S+).*System(.*)/) do 
    Regexp.last_match 
end 

grepます

はパターン===要素の列挙内の各要素の配列を返します。オプションのブロックが指定された場合、一致する各要素が渡され、ブロックの結果が出力配列に格納されます。

ので、ブロックを渡すことによって、我々は唯一のマッチラインのRegexp.last_matchの出力をINGのmap/collect本質的です。そしてRegexp.last_match

は、最後に成功したパターンマッチによって生成されたMatchDataオブジェクトを返します。

+0

ありがとうございます: 'Regexp。last_match'はコード臭のように感じますが、明らかにRubyの一部です。 –

0

この:

str.each_line.find { |l| m = l.match(/^(\S+).*System(.*)/) ; break m if m } 

はこれと同じです:

str.each_line.find { |l| l.match(/^(\S+).*System(.*)/) } 

あなたが戻ってすべての試合をしたい場合は、新しい結果を構築しています。それはあなたがおそらくreduceをしたい意味:

str.each_line.reduce([]) do |matches, line| 
    if match_data = line.match(/^(\S+).*System(.*)/) 
    matches << match_data 
    end 
    matches 
end 

つのループのみマッチデータを含む配列の結果と。あなたがやりたいgrepを使用することができ

+1

「mがmならば改行を返さずに行を返します。私は試合が欲しかった。 –

関連する問題