ある意味、前回の続き(配列から重複なくランダムに複数の値を得る方法 | while(isプログラマ))。
配列から指定の数分、ランダムで値を取得する関数を作ってみました。
function getRandValues(opt, arr){
var originalArr = [];
var randValArr = [];
obj = {
size:1,
min:1,
max:100,
step:1
};
for(var i in obj){
if(opt && opt[i]!==undefined){
obj[i] = opt[i];
}
}
if( !(arr instanceof Array) || (arr.length===0)){
if(arr instanceof Array){
originalArr = arr;
}
for(var i=obj['min'],j=0; i<=obj['max']; i+=obj['step'],j++){
originalArr[j] = i;
}
arr = originalArr;
}else{
originalArr = arr;
}
var rand, getVal;
for(var i=0;i<obj['size'];i++){
rand = Math.floor( Math.random() * originalArr.length);
getVal = originalArr.splice(rand,1);
randValArr.push(getVal[0]);
}
return randValArr;
}
第一引数にオプションを、第二引数にランダムの値を得る元の配列をいれます。
第一引数のオプションの説明は下記のとおりです。
- size:取得するランダム値の数。初期値は1
- min:配列を指定しない場合に取得するランダム値の最小値。初期値は1
- max:配列を指定しない場合に取得するランダム値の最大値。初期値は100
- step:配列を指定しない場合に取得するランダム値取得用の数列の値の差。初期値は1
例:
console.log(getRandValues()) // [5]など1~100の間の整数がランダムで一つ返す
console.log(getRandValues({ size:5, min:10, max:15, step:0.5})) // [10.5, 12, 15, 12.5, 13.5] など、10~15の間の交差が0.5の等差数列から5つの値をランダムで返す
var colorArr = ['red', 'green', 'blue', 'white', 'black'];
console.log(getRandValues({size:1},colorArr)) // ["blue"] など、配列からランダムで一つ返す
console.log(colorArr) // ["red", "green", "white", "black"] など、ランダムで取得した値を減らした配列となっている
ランダムの値を配列から複数取得するための関数ですが、sizeを0として、第二引数に長さが0の配列をいれると等差数列の配列を取得するということもできます。
var arr = [];
getRandValues({size:0, max:10}, arr);
console.log(arr); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] となる
var arr = [];
getRandValues({size:0, min:2,max:11,step:2}, arr);
console.log(arr); // [2, 4, 6, 8, 10] となる
var arr = [];
getRandValues({size:0, min:0,max:1,step:0.1}, arr);
console.log(arr); // [0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7, 0.7999999999999999, 0.8999999999999999, 0.9999999999999999] と想定とは違う結果に・・・。
最後の結果が想定と違う結果になってしまったのは、JavaScriptが浮動小数点型で計算しているためです。小数点の演算を扱うとたまに遭遇します(参考:参考:Javascriptで小数を含む計算を行うとき、計算結果の小数点2位以下を丸める。 | Scenee's blog)。
さて、関数を作ってみただけではなんなのでその関数の実用的な(かどうかは分かりませんが)サンプルを作ってみました。
JavaScriptでビンゴゲーム
ビンゴゲームです(本来、一人で楽しむためのものではないですが・・・)。
例えばビンゴシートのそれぞれの列を埋めるのに今回作成した関数を使っています。例えば、最も左の列をランダムな値で埋めるのは以下のようにやっています。
writeBingoSeat($('#bingo_seat div span:nth-child(1)'), getRandValues({size:5,min:1,max:15}) )
writeBingoSeatは第一引数にランダム値を入れる列を表すjQueryオブジェクトを入れて第二引数に数値配列を入れるとビンゴシートに数値を埋めていくメソッドです。第二引数には最小値が1、最大値が15の範囲の整数を5つ取得した配列を入れています。
他には、ビンゴの番号を選ぶのにも今回作成した関数を使っています。例えば以下の様な感じ。
var bingoNumbers = [];
$('#getNumBtn').click(function(){
var randVal = getRandValues({size:1,min:1,max:75,step:1}, bingoNumbers)[0];
});
詳しく知りたい方はページのソースを見てみてください。
こういうのは本来オブジェクト指向で書いたほうがいいんでしょうけどね・・・。まだまだオブジェクト指向はよく分かってません・・・。上司がJavaScriptをオブジェクト指向で書くようになったので、自分もそろそろ本格的にオブジェクト指向を勉強したほうがよさそうなんですが・・・。

コメント