ググってよく見かけたのは、Fisher-Yates shuffleというアルゴリズムを利用するもの。ソースのサンプルもほとんどが同じ。
function shuffle(ary) { var i = ary.length; while(i > 0){ var j = Math.floor(Math.random()*i), t = ary[--i]; ary[i] = ary[j]; ary[j] = t; } return ary; } var test = [1, 2, 3, 4, 5]; var test2 = shuffle(test); // ランダムに並び替えされる test; // test2と同等
ランダムシャッフル前の配列も変更される点に注意。
配列をランダムシャッフルするイメージ
- 配列の最後の値を入れ替える
- 配列の最後から2つめまでの配列で、最後から2つ目の値を入れ替える
- 配列の最後から3つめまでの配列で、最後から3つ目の値を入れ替える
- …
これを配列の数だけ繰り返す。
ランダムシャッフル前の配列も保持する場合
function shuffle(ary) { var ary = [].concat(ary), i = ary.length; while(i > 0){ var j = Math.floor(Math.random()*i), t = ary[--i]; ary[i] = ary[j]; ary[j] = t; } return ary; } var test = [1, 2, 3, 4, 5]; var test2 = shuffle(test); // ランダムに並び替えされる test; // ランダムシャッフル前のtestと同等
concatを使って配列をコピーして、コピーした配列をシャッフルして返却します。