2013-04-12 12 views
10

ランダムに並べ替えるオブジェクトの配列があります。この場合、array.shuffleを使用できます。しかし、後でその配列を同じ配列に再現したいのですが?後でこのシーケンスを再現できるように、種、乱数などを提供できる方法はありますか?ランダム配列ソートの再現

(MongoIDを使用して)MongoDBデータベースからオブジェクトのランダムなリストを生成したいので、そのリストを後で再生する必要があります。しかし、私が知る限り、MongoDBにランダムなソートを直接実装するのは本当に良い方法ではありません。多くのオブジェクト(> 1,000,000)がある可能性がありますが、計算時間は最初の試行では問題ではありません。

答えて

19

Ruby docs for Array#shuffleを見ると、Randomをジェネレータとして渡すことができます。新しいRandomを毎回同じシードを使用してシャッフルすると、同じ結果が得られます。

>> arr = %w{John Paul George Ringo} 
=> ["John", "Paul", "George", "Ringo"] 
>> arr.shuffle(random: Random.new(1)) 
=> ["Ringo", "John", "George", "Paul"] 
>> arr.shuffle(random: Random.new(1)) 
=> ["Ringo", "John", "George", "Paul"] 
>> arr.shuffle(random: Random.new(1)) 
=> ["Ringo", "John", "George", "Paul"] 

編集:これはかなり新しい各時間よりも(一方Randomを使用して、各個別のシャッフル及びshufflingsの配列の両方を繰り返すことができるようにArray#shuffleは、複数反復shufflingsを生成有するように拡張することができます同じ種子でそれを更新して繰り返す:

>> arr = [1, 2, 3, 4] => [1, 2, 3, 4] 
>> r = Random.new(17) => #<Random:0x000000017be4d0> 
>> arr.shuffle(random: r) => [3, 1, 4, 2] 
>> arr.shuffle(random: r) => [1, 3, 2, 4] 
>> arr.shuffle(random: r) => [4, 3, 2, 1] 
>> r = Random.new(17) => #<Random:0x00000001c60da8> 
>> arr.shuffle(random: r) => [3, 1, 4, 2] 
>> arr.shuffle(random: r) => [1, 3, 2, 4] 
>> arr.shuffle(random: r) => [4, 3, 2, 1] 
>> etc. 
?> 
+0

私の解決策よりもずっと良い。これを使って。 –

+1

クール、それはよさそうだ。そして私はあなたのビートルズの例が好きです;) – 23tux

+1

それを上品に保ちます。 – iamnotmaynard

2

メソッドのソース(http://ruby-doc.org/core-2.0/Array.html#method-i-shuffle)を見ると、ソートするためにRuby乱数ジェネレータにドロップされているようです。

それがある場合は、スクリプトを実行する前に、

srand *seed number* 

でシードを設定することができます。私はこれで100%ではないが、それは動作するようだが、私は確かに単体テストを書くだろう!