2

ランダム化を含む初心者の Ruby の問題の解決策として、次のコードを見つけました。Rubyにはshuffleメソッドがあることは承知していますが、私の質問の目的は特にpush.

def shuffle arr
    shuf = []
    while arr.length > 0

        # Randomly pick one element of the array.
        rand_index = rand(arr.length)

        # Now go through each item in the array,
        # putting them all into new_arr except for the # randomly chosen one, which goes into shuf. 

        curr_index = 0
        new_arr = []
        arr.each do |item|
            if curr_index == rand_index
                shuf.push item
            else
                new_arr.push item
            end

            curr_index = curr_index + 1
        end

        # Replace the original array with the new, # smaller array.
        puts arr.inspect
        arr = new_arr
    end
    shuf
end

shuffle_array = [1,2,3,4,5,6,7,8,9]
shuffle(shuffle_array)

コマンドラインでの出力は次のとおりです。

Rick:programs rickthomas$ ruby shuffleSolution.rb
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 8, 9]
[1, 2, 3, 4, 5, 8, 9]
[1, 2, 3, 4, 5, 9]
[1, 2, 3, 4, 9]
[1, 3, 4, 9]
[3, 4, 9]
[3, 9]
[3]
Rick:programs rickthomas$ 

while arr.length > 0この線から判断すると、arrが徐々に減少しているように見えます。これは、他の 2 つの配列のいずれかへのpushing項目によるものと思われます。arrこの仮定をテストするために、次のコードをいじっています。

array1 = [1,2,3,4,5,6,7,8]
array2 = []
array3 = []
array1.each do |x|
  random_num = rand(2)
  if random_num == 1
    array2.push x
  else
    array3.push x
  end
  puts array1.inspect

end

上記の方法と同様の方法で array1 が減少すると予想していましたshuffleが、代わりに次のようになりました。

Rick:programs rickthomas$ ruby socratesWork.rb
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8]
Rick:programs rickthomas$ 

push最初のスニペットでは配列項目を削除するのに、2 番目のスニペットでは削除しないのはなぜですか? どこかで構文エラーを見逃しているだけですか、それとももっと基本的なことを誤解していpushますか?

この質問に対する回答を既にスタック オーバーフローで検索しましたが、投稿された同様の質問はまだ見つかりませんでした。ruby-doc.org もチェックしましたが、配列への追加についてのみ説明されており、ある配列から別の配列へのアイテムの移動 (?) については言及されていませんでした。

4

3 に答える 3

2

さて、一致するインデックスを持つ要素を除くすべての要素を にプッシュしていnew_arrます。そのサイズは、反復ごとに 1 ずつ減少します。

于 2013-03-23T11:32:46.523 に答える
1

各反復で配列をより小さな配列に置き換えるようです。

 # Replace the original array with the new, # smaller array.
    puts arr.inspect
    arr = new_arr
于 2013-03-23T11:20:47.077 に答える
1

最初のスニペットでは、内側のループが元の配列arrを 2 つの部分に分割します。

  1. ランダムインデックスに一致し、配列にプッシュされる要素shuf
  2. ランダム インデックスに一致しない要素はnew_arr、各外側ループで空の配列として初期化される にプッシュされました。

したがって、外側のループごとに、shufもう 1 つの要素を取得し、ランダムに選択されnew_arrた要素を除いて、すべての要素を受け取ります。MAGICarrは外側のループの最後の行で出てきます。ここでは に割り当てられます。したがって、すべてのループは 1 つの要素が小さくなります。それは の魔法でも副作用でもありません。new_arrarrarrArray#push

于 2013-03-23T12:22:39.010 に答える