1

RubyでSaaSコースをやっています。演習では、イテレータ、ブロック、および歩留まりを使用して、2つのシーケンスのデカルト積を計算するように求められます。

私は純粋な推測とエラーによってこれに行き着きました、そしてそれはうまくいくようです。しかし、その方法はわかりません。基本ブロックと歩留まりの使い方は理解しているようですが、これは?全くない。

class CartProd
  include Enumerable
  def initialize(a,b)
        @a = a
        @b = b
  end
  def each
        @a.each{|ae|
                @b.each{|be|
                        yield [ae,be]
                }
        }
  end
end

私のような初心者のための説明をお願いします。

(追記:必要なクラス名をCartProdに変更したので、コースを受講している人は、グーグルで簡単に回答を見つけることができません)

4

3 に答える 3

7

これを段階的に構築していきましょう。クラスのコンテキストから外すことで、物事を少し単純化します。

この例では、イテレータを従来のforループのより強力な代替品と考えるのが直感的です。

したがって、最初にforループバージョンを示します。

seq1 = (0..2)
seq2 = (0..2)
for x in seq1
  for y in seq2
    p [x,y] # shorthand for puts [x, y].inspect
  end
end  

do...end次に、これをよりRubyの慣用的なイテレータスタイルに置き換えて、実行するブロック(つまり、ブロック)を明示的に指定します。

seq1.each do |x|
  seq2.each do |y|
    p [x,y]
  end
end

これまでのところ、デカルト積を印刷しました。今、あなたの割り当てはあなたにも使うように頼みますyield。のポイントyieldは、「実行を譲る」ことです。つまり、制御を一時的に別のコードブロックに渡します(オプションで1つ以上の引数を渡します)。

したがって、このおもちゃの例では実際には必要ありませが、上記のように値を直接yield出力する代わりに、値を指定して、呼び出し元にその値を受け入れるブロックを提供させ、代わりに出力させることができます。

これは次のようになります。

 def prod(seq1, seq2)
    seq1.each do |x|
      seq2.each do |y|
        yield [x,y]
      end
    end
  end

このように呼び出すことができます:

prod (1..2), (1..2) do |prod| p prod end

は、内部ループのyield実行ごとに製品を提供し、生成された値は、呼び出し元によって提供されたブロックによって出力されます。

于 2012-10-06T13:49:48.383 に答える
0

ここで正確に何がわかりませんか?可能なすべての要素のペアを生成するイテレータを作成しました。ブロックを渡すCartProd#eachと、実行a.length*b.length回数になります。forこれは、他のプログラミング言語で2つの異なるサイクルを互いに折りたたむようなものです。

于 2012-10-06T12:31:58.480 に答える
0

yieldは、メソッド呼び出しの一部として渡されたコードのブロックに制御を渡す(yield)だけです。yieldキーワードの後の値は、引数としてブロックに渡されます。ブロックの実行が完了すると、ブロックは制御を戻します。

したがって、あなたの例では、次のように#eachを呼び出すことができます。

CartProd.new([1, 2], [3, 4]).each do |pair|
  # control is yielded to this block
  p pair
  # control is returned at end of block
end

これにより、値の各ペアが出力されます。

于 2012-10-06T13:29:43.853 に答える