jquery JavaScript で重複のない乱数を生成する

2013年4月26日

重複のない乱数を生成して配列に格納して返す方法。

パラメータに生成する乱数の数を受け取り、重複のない整数の乱数を発生させ、配列に入れて返す関数を作成。例えばパラメータに 10 を指定すると 0 から 9 の間の10個の重複のない整数をランダムに生成する。

  • パラメータ count の数だけ乱数を発生させる。
  • Math.random()で取得した値に「count」をかけて、Math.floor() で切り下げて整数にする。
  • すでに同じ数値が生成されているかは、すでに生成した乱数と発生した乱数を比較。
  • 異なる値が発生されるまで繰り返し。
function generate_randomx(count) {
  //生成した乱数を格納する配列を初期化
  var generated = new Array();
  //生成した乱数を格納している配列の長さ(生成した乱数の数)
  var generatedCount = generated.length;
  //パラメータ count の数だけ Math.random()で乱数を発生
  for(var i = 0 ; i < count; i++){   
    var candidate = Math.floor(Math.random() * count);
    //今まで生成された乱数と同じ場合は再度乱数を発生
    for(var j = 0; j < generatedCount; j++) {  // このコメントは無視>
      if(candidate == generated[j]){
        candidate = Math.floor(Math.random() * count);
        j= -1;
      }
    }
    generated[i] = candidate;  
    generatedCount++;
  }
  return generated;  
}
<!-- comment only -->

確認方法。
配列の中身は toString() メソッドで、配列内の要素をカンマ連結した文字列として確認できる。
以下の場合は、内部的に toString() メソッドが呼び出される。

alert(generate_randomx(15));

クリックすると乱数を表示 

Math.random()
戻り値:0.0から1.0まで(1未満)の疑似乱数。
Math.floor()
指定された引数の値に等しいかそれ以下で最も近い整数値を返す(切り下げ)
パラメータ:任意の数値または数式。

0以上10未満のランダムな整数を取得する例

var rand = Math.floor( Math.random() * 10 );

1番目の数を必ず特定の値にするようにする場合は、以下のようにする。

//count:生成する乱数の数
//num: 1番目の数値を指定(必ずその数値を1番目にもってくる)。値の範囲は0~count-1 (オプション)
function generate_randomx(count, num) {
  var generated = new Array();
  var generatedCount = generated.length;
  //num: 1番目の数値の指定がある場合
  if(num || num === 0 ) {
    for(var i = 0 ; i < count; i++){  // このコメントは無視>
      //1番目の数値(generated[0])を num の値にする
      if(i === 0) {
        var candidate = num;
        generated[i] = candidate;  
        generatedCount++;
        continue;
      }
      candidate = Math.floor(Math.random() * count);
      //今まで出力された数字と同じ場合は再度乱数を発生
      for(var j = 0; j < generatedCount; j++) { // このコメントは無視>
        if(candidate == generated[j]){
          candidate = Math.floor(Math.random() * count);
          j= -1;
        }
      }
      generated[i] = candidate;  
      generatedCount++;
    }
  }else{
    for( i = 0 ; i < count; i++){  
      candidate = Math.floor(Math.random() * count);
       //今まで出力された数字と同じ場合は再度乱数を発生
       for( j = 0; j < generatedCount; j++) {  // このコメントは無視>
         if(candidate == generated[j]){
           candidate = Math.floor(Math.random() * count);
           j= -1;
         }
       }
       generated[i] = candidate;  
       generatedCount++;
     }
  }
  return generated;  
}
<!-- comment only -->