配列をシャッフルする「Fisher-Yates法」というのがあるみたいなんだけど、
欲しいのはindexを並べ替えたものだけで
いちいち配列に数字を入れてからシャッフルするのも面倒なので
配列のiとかjの場所に数値がなければ、iとjをそのまま使うようにした。
function randomIndex(n){
var i, j, tmp, a = new Array(n);
a[0] = 0;
for(i = n - 1; i > 0; i--) {
j = Math.floor(Math.random() * (i+1));
tmp = a[i] || i;
a[i] = a[j] || j;
a[j] = tmp;
};
return a;
}
console.log(randomIndex(10));
console.log(randomIndex(10));
console.log(randomIndex(10));
console.log(randomIndex(10));
console.log(randomIndex(10));
全indexの配列を先に作るのは無駄な気がしてきたので、
クロージャにして呼び出すたびに計算させるようにしてみた。
指定した数未満の数字を重複なしに呼び出して、全部出し終わったらnullを返す。
function makeBingo(n){
var i, j, tmp, a = new Array(n);
return function (){
if(n > 0){
i = n - 1;
j = Math.floor(Math.random() * (n));
tmp = a[i] || i;
a[i] = a[j] || j;
a[j] = tmp;
n = i;
return a[i];
}else{
return null;
}
}
};
var bingo = makeBingo(10);
for(var i=bingo();i!=null;i=bingo()){
console.log(i);
};
2018/07/27 追記
こういうのを書きたかったということ。
var hukubiki = [
"5等 ティッシュ1箱",
"5等 ティッシュ1箱",
"5等 ティッシュ1箱",
"5等 ティッシュ1箱",
"5等 ティッシュ1箱",
"5等 ティッシュ1箱",
"4等 クッキー詰め合わせ",
"4等 クッキー詰め合わせ",
"4等 クッキー詰め合わせ",
"4等 クッキー詰め合わせ",
"3等 炊飯器",
"3等 炊飯器",
"3等 炊飯器",
"2等 大型テレビ",
"2等 大型テレビ",
"1等 ペアでハワイ旅行"
];
var bingo = makeBingo(hukubiki.length);
for(var i=bingo();i!=null;i=bingo()){
console.log(hukubiki[i]);
};