5

各要素が 2 つの整数の配列 (たとえば、[3,5]) である配列を反復処理したい。これらの要素ごとに、2 つの整数の合計を計算し、これらの合計のいずれかが特定の任意の値を超えたときにループを終了します。ソース配列は非常に大きく、必要な値が最初の近くにある可能性が高いため、不要な要素をすべてループするのは適切なオプションではありません。

これを行うために 3 つのループを作成しましたが、そのすべてで目的の結果が得られます。私の質問は、どちらがより慣用的な Ruby ですか? それとも、もっと良い方法がありますか? 非ローカル ループ変数を使用しないようにしていますが、breakステートメントは私の (確かに初心者の) 目にはハックのように見えます。

# Loop A
pairs.each do |pair|
  pair_sum = pair.inject(:+) 
  arr1 << pair_sum
  break if pair_sum > arr2.max
end

#Loop B - (just A condensed)
pairs.each { |pair| arr1.last <= arr2.max ? arr1 << pair.inject(:+) : break }

#Loop C
i = 0
pair_sum = 0
begin
  pair_sum = pairs[i].inject(:+)
  arr1 << pair_sum
  i += 1
end until pair_sum > arr2.max

Ruby の早い段階で .each { } イテレーションをエスケープする際にも同様の質問がありましたが、基本的には.eachorを使用してターゲット インデックスに到達したときに.each_with_index終了するのは機能するが、より慣用的な回答でした。ただし、私の状況では、反復する必要がある要素の数が事前にわからないため、境界ケースのように見えます。break.take(num_elements).each

これは、私がすでに解決したプロジェクト オイラー タイプの問題からのものです。コミュニティが好む構文について疑問に思っています。貴重な時間をありがとうございました。

4

4 に答える 4

8

take固定数の要素を提供する代わりに、ブロックを提供するdropバリアントと場所がtake_whileあります。drop_whileブロックが true を返す限り、Ruby は受信側 (take_while の場合) からの値を累積します。あなたのコードは次のように書き直すことができます

array.take_while {|pair| pair.sum < foo}.map(&:sum)

これは、これらのペアの一部の合計を 2 回計算することを意味します。

于 2013-04-30T08:54:27.593 に答える
1
[[1, 2], [3, 4], [5, 6]].find{|x, y| x + y > 6}.inject(:+)
#=> 7
于 2013-04-30T09:58:05.053 に答える