Enumerable::take
ここでの方法については、私にはわからないことがあります。私のコードはn
、連続する素数のサイズ配列のリストを生成することになっています。
このnext
メソッドを使用すると問題なく動作しtake(n)
ますが、説明できないものが返されます。コードは次のとおりです。
編集 ここではshift
方法が問題のようです(以下を参照)。理由はまだわかりませんが
require 'prime'
def consecutives(size)
Enumerator.new do |enum|
ps = Prime.lazy # all primes numbers
a = Prime.take(size) # itinialize the array
size.times{ps.next} # skip the first <size> values from ps
loop do
enum << a # return result
a << ps.next # add next prime number
a.shift # remove first item from a
end
end
end
c3 = consecutives(3) #create an iterator for arrays of size 3
現在、使用next
は問題なく機能します。
3.times { p c3.next} #=> [[2,3,5],[3,5,7],[5,7,11]]
take
私がまったく得られない何かを返すのに対して:
p c3.take(3) #=> [[5, 7, 11], [5, 7, 11], [5, 7, 11]]
ここで何が起こっているのかについて何か考えはありますか?
編集置換a << ps.next ; a.shift
によってa = (a+ [ps.next])[-1..1]
実際に問題が解決され、列挙子は期待どおりに動作します。私はまだここで何が起こっているのかわからないので、質問は関連性があると思います。
問題:
enum << a # return result
ここで配列を生成します。またはそう思います。内部では、配列への参照が渡されます。次に、内部と思われる配列を変更します。実際には、これらの変更は両方の配列に影響します。これは、メモリ内に実際には1つの配列と、それに対する2つの参照しかないためです。最終的に、同じ1つの配列と4つの参照(1つは内部配列で3つは生成されます)を取得します。
見つかった回避策は、そこで新しい配列を作成するために機能します。単に電話.dup
するだけでも十分です。
require 'prime'
def consecutives(size)
Enumerator.new do |enum|
ps = Prime.lazy
a = Prime.take(size)
size.times{ps.next}
loop do
enum << a.dup # <== here
a << ps.next
a.shift
end
end
end
c3 = consecutives(3)
c3.take(3) # => [[2, 3, 5], [3, 5, 7], [5, 7, 11]]
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加