JavaScript の配列からランダムで要素を取り出して扱いたいということがあるのですが、安易にやろうとしたら重複した値がでてきたり、 splice でその要素を除いたりしてやっていたのですが、どうも動作安定していない感じだったので、自分の中で再度見直しとしてのメモエントリー。
重複なくランダムに複数の要素を取り出すコード
以下のページのスクリプトを利用させていただきました。
function random(array, num) {
var a = array;
var t = [];
var r = [];
var l = a.length;
var n = num < l ? num : l;
while (n-- > 0) {
var i = Math.random() * l | 0;
r[n] = t[i] || a[i];
--l;
t[i] = t[l] || a[l];
}
return r;
}
var test_array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
random(test_array, 5);
変数 a
はチェックする配列を、 t
と r
は、配列の宣言・初期化、l
は a配列の個数、 n
は 取り出す個数でもしも指定がなかったり、チェックする配列数より多ければ a配列の数だけ。
while の繰り返しは、 指定した数を減らしていって回数分回す。 randomな数を作り、用意したa配列からrandomの数の部分を抜き出してt配列とr配列を組み合わせて、新しい配列完了!なしくみの様子。配列を組み合わせてゴニョゴニョする部分の記載は省略。(書くのがめんd(ry
10回やってみた結果
random(test_array, 5);
[1, 4, 7, 0, 3]
random(test_array, 5);
[5, 9, 3, 7, 2]
random(test_array, 5);
[2, 9, 7, 4, 3]
random(test_array, 5);
[1, 8, 3, 9, 4]
random(test_array, 5);
[2, 3, 6, 0, 5]
random(test_array, 5);
[1, 4, 5, 0, 7]
random(test_array, 5);
[4, 6, 9, 5, 7]
random(test_array, 5);
[9, 7, 8, 0, 3]
random(test_array, 5);
[5, 6, 1, 4, 7]
random(test_array, 5);
[9, 7, 0, 8, 3]
この方法で重複なしで配列からランダムに抜き出しできるのがわかりました。
重複しないで抜き出すところ、比較的簡易なコードで行けているのがびっくりだったりします。