webdevqa.jp.net

JavaScriptで特定の範囲でランダムな整数を生成する?

JavaScriptで指定された2つの変数間にランダムな整数を生成するにはどうすればよいですか。 x = 4y = 84, 5, 6, 7, 8のどれかを出力しますか?

1706
zacharyliu

Mozilla Developer Network ページにいくつかの例があります。

/**
 * Returns a random number between min (inclusive) and max (exclusive)
 */
function getRandomArbitrary(min, max) {
    return Math.random() * (max - min) + min;
}

/**
 * Returns a random integer between min (inclusive) and max (inclusive).
 * The value is no lower than min (or the next integer greater than min
 * if min isn't an integer) and no greater than max (or the next integer
 * lower than max if max isn't an integer).
 * Using Math.round() will give you a non-uniform distribution!
 */
function getRandomInt(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

これがその背後にある論理です。これは単純な3つの規則です。

Math.random()は、0(包括的)から1(排他的)までのNumberを返します。だから私たちはこのような間隔があります:

[0 .................................... 1)

さて、私たちはmin(包括的)とmax(排他的)の間の数をお願いします。

[0 .................................... 1)
[min .................................. max)

Math.randomを使用して、[min、max)の間隔で通信相手を取得できます。しかし、最初に、2番目の区間からminを引くことによって、問題を少し考慮する必要があります。

[0 .................................... 1)
[min - min ............................ max - min)

これは与える:

[0 .................................... 1)
[0 .................................... max - min)

Math.randomを適用してから、通信員を計算します。乱数を選択しましょう。

                Math.random()
                    |
[0 .................................... 1)
[0 .................................... max - min)
                    |
                    x (what we need)

それで、xを見つけるために、我々はするでしょう:

x = Math.random() * (max - min);

[min、max)の間隔で数が得られるように、minを追加し直すことを忘れないでください。

x = Math.random() * (max - min) + min;

それがMDNの最初の機能でした。 2番目のものは、minmaxの間の整数を返します。

今整数を得るために、あなたはroundceilまたはfloorを使うことができます。

あなたはMath.round(Math.random() * (max - min)) + minを使うことができました、しかしこれは非一様分布を与えます。 minmaxはどちらも、ロールするチャンスがおよそ半分しかありません。

min...min+0.5...min+1...min+1.5   ...    max-0.5....max
└───┬───┘└────────┬───────┘└───── ... ─────┘└───┬──┘   ← Math.round()
   min          min+1                          max

maxが間隔から除外されているので、minよりもさらにロールする可能性が低くなります。

Math.floor(Math.random() * (max - min +1)) + minを使えば、あなたは完全に均等な分布をしています。

min.... min+1... min+2 ... max-1... max.... max+1 (is excluded from interval)
|        |        |         |        |        |
└───┬───┘└───┬───┘└─── ... ┘└───┬───┘└───┬───┘   ← Math.floor()
   min     min+1               max-1    max

maxはロールする可能性がわずかに少なくなったため、その式でceil()-1を使用することはできませんが、(不要な)min-1の結果もロールすることができます。

3432
Ionuț G. Stan
var randomnumber = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
490
Darin Dimitrov

Math.random()

Mozilla Developer Networkのドキュメントから。

// Returns a random integer between min (include) and max (include)

Math.floor(Math.random() * (max - min + 1)) + min;

便利な例

// 0 - 10
Math.floor(Math.random() * 11);

// 1 - 10
Math.floor(Math.random() * 10) + 1;

// 5 - 20
Math.floor(Math.random() * 16) + 5;

// -10 - (-2)
Math.floor(Math.random() * 9) - 10;
101
Lior Elrom
function getRandomizer(bottom, top) {
    return function() {
        return Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom;
    }
}

使用法:

var rollDie = getRandomizer( 1, 6 );

var results = ""
for ( var i = 0; i<1000; i++ ) {
    results += rollDie() + " ";    //make a string filled with 1000 random numbers in the range 1-6.
}

壊す:

(関数型プログラミングから借用して)関数を返しています。これは呼び出されると、値bottomtopの間のランダムな整数を返します。返される可能性がある数値の範囲に、最下位と最上位の両方を含めたいので、「包含的」と言います。このように、getRandomizer( 1, 6 )は1、2、3、4、5、または6を返します。

(下が小さい番号、上が大きい番号)

Math.random() * ( 1 + top - bottom )

Math.random()は0から1の間のランダムな倍精度を返し、それに1を加えてtopbottomの間の差を乗じると、01+b-aの間のどこかに倍精度が得られます。

Math.floor( Math.random() * ( 1 + top - bottom ) )

Math.floorは、数値を最も近い整数に切り捨てます。これで、0top-bottomの間のすべての整数が得られました。 1は紛らわしいように見えますが、我々は常に切り捨てているのでそこにある必要があります、それで実際にそれなしでトップの数に達することは決してないでしょう。生成するランダムな10進数は、0から(1+top-bottom)の範囲内にある必要があります。その結果、切り捨てて0からtop-bottomの範囲のintを取得できます。

Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom

前の例のコードでは0top-bottomの範囲の整数が得られたので、次に必要なのはbottomを追加してbottomtopの範囲の整数を取得することだけです。 :D


注意:最初に非整数値またはそれ以上の数値を渡すと、望ましくない動作になりますが、誰かがそれを要求しない限り、元の質問の意図からは程遠いので、引数チェックコードについて詳しく調べません。 。

53

1から10までの乱数を返します。

Math.floor((Math.random()*10) + 1); 

1から100までの乱数を返します。

Math.floor((Math.random()*100) + 1)
29
Prasobh.K
function randomRange(min, max) {
  return ~~(Math.random() * (max - min + 1)) + min
}

Underscore.jsを使用している場合は代替手段

_.random(min, max)
28
Codler

他の答えは01の完全に合理的なパラメータを説明しません。代わりにroundまたはceilfloor 代わりに を使用してください。

function randomNumber(minimum, maximum){
    return Math.round( Math.random() * (maximum - minimum) + minimum);
}

console.log(randomNumber(0,1));  # 0 1 1 0 1 0
console.log(randomNumber(5,6));  # 5 6 6 5 5 6
console.log(randomNumber(3,-1)); # 1 3 1 -1 -1 -1
14
Starkers

あなたが0からmaxまでの間の変数を必要とするならば、あなたは使うことができます:

Math.floor(Math.random() *  max);
12

コンピュータプログラムを使用して乱数を生成した後、選択した数が最初の数の一部または全部である場合、それは依然として乱数と見なされます。しかし、それが変更された場合、 数学者はそれを乱数として受け入れず、偏った数と呼ぶことができます。 しかし、もしあなたが単純なタスクのためのプログラムを開発しているなら、これは考慮すべきケースではないでしょう。 しかし、あなたが宝くじプログラムやギャンブルゲームのような貴重なもののために乱数を生成するためのプログラムを開発しているなら、あなたが上記の場合について考えていないなら、あなたのプログラムは管理によって拒絶されるでしょう。

そのような人々のために、これが私の提案です。

Math.random()を使用して乱数を生成します(これをnと言います)。

Now for [0,10) ==>  n*10 (i.e. one digit) and for[10,100) ==> n*100 (i.e. two digits) and so on. Here squire bracket indicates that boundary is inclusive and round bracket indicates boundary is exclusive.
Then remove the rest after the decimal point. (i.e. get floor) - using Math.floor(), this can be done.

あなたが乱数を選ぶために乱数表を読む方法を知っていれば、あなたは上のプロセスを知っています(1、10、100などを掛ける)は私が最初に述べたものに違反していません(それが変わるだけなので)。小数点の位置)

次の例を検討して、あなたのニーズに合わせて開発してください。

あなたがサンプル[0,9]を必要とするならばn * 10の床はあなたの答えであり、そして必要なら[0,99]それからn * 100の床はあなたの答えです。

今すぐあなたの役割に入りましょう:

あなたは特定の範囲内の数字を尋ねました。 (この場合、あなたはその範囲に偏っています。 - ダイスを振ることによって[1,6]から数字を取ることによって、あなたは[1,6]に偏っていますが、それでもダイが偏っていない場合に限りランダムです。 。)

だからあなたの範囲を考慮してください==> [78、247]範囲の要素数= 247 - 78 + 1 = 170; (両方の境界が包含的なので。

/*Mthod 1:*/
    var i = 78, j = 247, k = 170, a = [], b = [], c, d, e, f, l = 0;
    for(; i <= j; i++){ a.Push(i); }
    while(l < 170){
        c = Math.random()*100; c = Math.floor(c);
        d = Math.random()*100; d = Math.floor(d);
        b.Push(a[c]); e = c + d;
        if((b.length != k) && (e < k)){  b.Push(a[e]); }
        l = b.length;
    }
    console.log('Method 1:');
    console.log(b);
/*Method 2:*/

    var a, b, c, d = [], l = 0;
    while(l < 170){
        a = Math.random()*100; a = Math.floor(a);
        b = Math.random()*100; b = Math.floor(b);
        c = a + b;
        if(c <= 247 || c >= 78){ d.Push(c); }else{ d.Push(a); }
        l = d.length;
    }
    console.log('Method 2:');
    console.log(d);

注:方法1では、最初に必要な数字を含む配列を作成し、次にそれらを別の配列にランダムに入れました。方法2では、ランダムに番号を生成し、それらが必要な範囲内にあることを確認します。それを配列に入れます。ここで私は2つの乱数を生成し、有用な数を得る失敗率を最小にすることによってプログラムのスピードを最大にするためにそれらの合計を使用しました。しかしながら、生成された数を加えることはまたいくらかの好意を与えるでしょう。だから私は私の最初の方法は特定の範囲内で乱数を生成することをお勧めします。

どちらの方法でも、コンソールに結果が表示されます(Chromeでf12キーを押すとコンソールが開きます)。

11

これは、JavaScriptでのRandomクラスのMS DotNet実装です。

var Random = (function () {
function Random(Seed) {
    if (!Seed) {
        Seed = this.milliseconds();
    }
    this.SeedArray = [];
    for (var i = 0; i < 56; i++)
        this.SeedArray.Push(0);
    var num = (Seed == -2147483648) ? 2147483647 : Math.abs(Seed);
    var num2 = 161803398 - num;
    this.SeedArray[55] = num2;
    var num3 = 1;
    for (var i_1 = 1; i_1 < 55; i_1++) {
        var num4 = 21 * i_1 % 55;
        this.SeedArray[num4] = num3;
        num3 = num2 - num3;
        if (num3 < 0) {
            num3 += 2147483647;
        }
        num2 = this.SeedArray[num4];
    }
    for (var j = 1; j < 5; j++) {
        for (var k = 1; k < 56; k++) {
            this.SeedArray[k] -= this.SeedArray[1 + (k + 30) % 55];
            if (this.SeedArray[k] < 0) {
                this.SeedArray[k] += 2147483647;
            }
        }
    }
    this.inext = 0;
    this.inextp = 21;
    Seed = 1;
}
Random.prototype.milliseconds = function () {
    var str = new Date().valueOf().toString();
    return parseInt(str.substr(str.length - 6));
};
Random.prototype.InternalSample = function () {
    var num = this.inext;
    var num2 = this.inextp;
    if (++num >= 56) {
        num = 1;
    }
    if (++num2 >= 56) {
        num2 = 1;
    }
    var num3 = this.SeedArray[num] - this.SeedArray[num2];
    if (num3 == 2147483647) {
        num3--;
    }
    if (num3 < 0) {
        num3 += 2147483647;
    }
    this.SeedArray[num] = num3;
    this.inext = num;
    this.inextp = num2;
    return num3;
};
Random.prototype.Sample = function () {
    return this.InternalSample() * 4.6566128752457969E-10;
};
Random.prototype.GetSampleForLargeRange = function () {
    var num = this.InternalSample();
    var flag = this.InternalSample() % 2 == 0;
    if (flag) {
        num = -num;
    }
    var num2 = num;
    num2 += 2147483646.0;
    return num2 / 4294967293.0;
};
Random.prototype.Next = function (minValue, maxValue) {
    if (!minValue && !maxValue)
        return this.InternalSample();
    var num = maxValue - minValue;
    if (num <= 2147483647) {
        return parseInt((this.Sample() * num + minValue).toFixed(0));
    }
    return this.GetSampleForLargeRange() * num + minValue;
};
Random.prototype.NextDouble = function () {
    return this.Sample();
};
Random.prototype.NextBytes = function (buffer) {
    for (var i = 0; i < buffer.length; i++) {
        buffer[i] = this.InternalSample() % 256;
    }
};
return Random;
}());

つかいます:

        var r = new Random();
        var nextInt = r.Next(1, 100); //returns an integer between range
        var nextDbl = r.NextDouble(); //returns a random decimal
11
Ariful Islam

範囲を持つ乱数整数の場合は、次のことを試してください。

function random(minimum, maximum) {
  var bool = true;

  while (bool) {
    var number = (Math.floor(Math.random() * maximum + 1) + minimum);
    if (number > 20) {
      bool = true;
    } else {
      bool = false;
    }
  }

  return number;
}
9
user1764199

乱数を取得するには、まず1から6の間で、次のようにします。

    0.5 + (Math.random() * ((6 - 1) + 1))

これは乱数に6を掛けてから0.5を加えます。次に、次のようにして数値を正の整数に丸めます。

    Math.round(0.5 + (Math.random() * ((6 - 1) + 1))

これは、最も近い整数に数値を四捨五入します。

もっとわかりやすくするには、次のようにします。

    var value = 0.5 + (Math.random() * ((6 - 1) + 1))
    var roll = Math.round(value);
    return roll;

一般に、変数を使用してこれを行うためのコードは次のとおりです。

    var value = (Min - 0.5) + (Math.random() * ((Max - Min) + 1))
    var roll = Math.round(value);
    return roll;

最小値から0.5を取り除く理由は、最小値を単独で使用すると、最大値より1大きい整数を取得できるようになるためです。最小値から0.5を取り除くことによって、あなたは本質的に最大値が切り上げられるのを防いでいます。

それが役立つことを願っています。

7
Learner.js

次のコードを使うと、与えられた範囲で、繰り返しなしで乱数の配列を生成できます。

function genRandomNumber(how_many_number,min,max) {

            // parameters
            // how_many_number : how many numbers you want to generate. For example it is 5.
            // min(inclusive) : minimum/low value of a range. it must be any positive integer but less than max. i.e 4
            // max(inclusive) : maximun value of a range. it must be any positive integer. i.e 50
            // return type: array

            var random_number = [];
            for (var i = 0; i < how_many_number; i++) {
                var gen_num = parseInt((Math.random() * (max-min+1)) + min);
                do {
                    var is_exist = random_number.indexOf(gen_num);
                    if (is_exist >= 0) {
                        gen_num = parseInt((Math.random() * (max-min+1)) + min);
                    }
                    else {
                        random_number.Push(gen_num);
                        is_exist = -2;
                    }
                }
                while (is_exist > -1);
            }
            document.getElementById('box').innerHTML = random_number;
        }
7
Yusuf

私はこの質問がすでに答えられていることを知っていますが、私の答えは誰かに役立つかもしれません。

私はW3Schoolsでこの簡単な方法を見つけました:

Math.floor((Math.random() * max) + min);

これが誰かに役立つことを願っています。

7
NutCracker

最低と最高の間のランダムな整数:

function randomRange(l,h){
  var range = (h-l);
  var random = Math.floor(Math.random()*range);
  if (random === 0){random+=1;}
  return l+random;
}

最もエレガントな解決策ではありません。

6
brooklynsweb
function rnd(min,max){
    return Math.floor(Math.random()*(max-min+1)+min );
}
5
Aylian Craspa

これが私が乱数を生成するために使うものです。

function random(high,low) {
    high++;
    return Math.floor((Math.random())*(high-low))+low;
}

high++を実行します。なぜなら_Math.random()は、0、(両端を含む)、1(exclusive)の間の乱数を生成するからです。それから、高から低を引いて、生成する最高の数 - 低、次に+低、高を通常に戻し、最低の数を最低にします。それから結果の数を返します

random(7,3)3,4,5,6, or 7を返す可能性があります

5
Travis
function getRandomInt(lower, upper)
{
    //to create an even sample distribution
    return Math.floor(lower + (Math.random() * (upper - lower + 1)));

    //to produce an uneven sample distribution
    //return Math.round(lower + (Math.random() * (upper - lower)));

    //to exclude the max value from the possible values
    //return Math.floor(lower + (Math.random() * (upper - lower)));
}

この機能、およびこの機能のバリエーションをテストするには、以下のHTML/JavaScriptをファイルに保存してブラウザで開きます。コードは100万の関数呼び出しの分布を示す グラフ を作成します。このコードはEdgeのケースも記録するので、関数が最大値よりも大きい値、または最小値より小さい値を生成した場合は、you.will.know.about.itとなります。

<html>
    <head>
        <script type="text/javascript">
        function getRandomInt(lower, upper)
        {
            //to create an even sample distribution
            return Math.floor(lower + (Math.random() * (upper - lower + 1)));

            //to produce an uneven sample distribution
            //return Math.round(lower + (Math.random() * (upper - lower)));

            //to exclude the max value from the possible values
            //return Math.floor(lower + (Math.random() * (upper - lower)));
        }

        var min = -5;
        var max = 5;

        var array = new Array();

        for(var i = 0; i <= (max - min) + 2; i++) {
          array.Push(0);
        }

        for(var i = 0; i < 1000000; i++) {
            var random = getRandomInt(min, max);
            array[random - min + 1]++;
        }

        var maxSample = 0;
        for(var i = 0; i < max - min; i++) {
            maxSample = Math.max(maxSample, array[i]);
        }

        //create a bar graph to show the sample distribution
        var maxHeight = 500;
        for(var i = 0; i <= (max - min) + 2; i++) {
            var sampleHeight = (array[i]/maxSample) * maxHeight;

            document.write('<span style="display:inline-block;color:'+(sampleHeight == 0 ? 'black' : 'white')+';background-color:black;height:'+sampleHeight+'px">&nbsp;[' + (i + min - 1) + ']:&nbsp;'+array[i]+'</span>&nbsp;&nbsp;');
        }
        document.write('<hr/>');
        </script>
    </head>
    <body>

    </body>
</html>
4
Chris

これは、Math.random()を使用せずに、指定された長さの乱数を生成できるjavascript関数の例です。

    function genRandom(length)
    {
     const t1 = new Date().getMilliseconds();
     var min = "1",max = "9";
     var result;
     var numLength = length;
     if (numLength != 0)
     {
        for (var i = 1; i < numLength; i++)
        {
           min = min.toString() + "0";
           max = max.toString() + "9";
        }
     } 
     else
     {
        min = 0;
        max = 0;
        return; 
     }

      for (var i = min; i <= max; i++)
      {
           //Empty Loop
      }

      const t2 = new Date().getMilliseconds();
      console.log(t2);
      result = ((max - min)*t1)/t2;
      console.log(result);
      return result;
    }
4
Nilesh Pawar
    <!DOCTYPE html>
<html>
    <head>
            <meta charset="utf-8" />
    </head>
    <body>
        <script>
            /*

                assuming that window.crypto.getRandomValues is available
                the real range would be fron 0 to 1,998 instead of 0 to 2,000
                See javascript documentation for explanation
                https://developer.mozilla.org/en-US/docs/Web/API/RandomSource/getRandomValues
            */
            var array = new Uint8Array(2);
            window.crypto.getRandomValues(array);
            console.log(array[0] + array[1]);

        </script>
    </body>
</html>

Uint8Arrayは最大999となる3桁までの数字で埋められた配列を作成します。このコードは非常に短いです。

4
happy

これは私が底から指数の範囲内の乱数を取得したいのと同じように、範囲内の乱数を考慮したものです。例えばbase = 10、exponent = 2は、0から100までの理想的な乱数を与えます。

それがそれを使用するのを助けるならば、ここにそれはあります:

// get random number within provided base + exponent
// by Goran Biljetina --> 2012

function isEmpty(value){
    return (typeof value === "undefined" || value === null);
}
var numSeq = new Array();
function add(num,seq){
    var toAdd = new Object();
     toAdd.num = num;
     toAdd.seq = seq;
     numSeq[numSeq.length] = toAdd;
}
function fillNumSeq (num,seq){
    var n;
    for(i=0;i<=seq;i++){
        n = Math.pow(num,i);
        add(n,i);
    }
}
function getRandNum(base,exp){
    if (isEmpty(base)){
        console.log("Specify value for base parameter");
    }
    if (isEmpty(exp)){
        console.log("Specify value for exponent parameter");
    }
    fillNumSeq(base,exp);
    var emax;
    var eseq;
    var nseed;
    var nspan;
    emax = (numSeq.length);
    eseq = Math.floor(Math.random()*emax)+1;
    nseed = numSeq[eseq].num;
    nspan = Math.floor((Math.random())*(Math.random()*nseed))+1;
    return Math.floor(Math.random()*nspan)+1;
}

console.log(getRandNum(10,20),numSeq);
//testing:
//getRandNum(-10,20);
//console.log(getRandNum(-10,20),numSeq);
//console.log(numSeq);
3
Goran B.

あなたはあなたにこのコードスニペットをすることができます

let randomNumber = function(first,second){
let number = Math.floor(Math.random()*Math.floor(second));
while(number<first){

    number = Math.floor(Math.random()*Math.floor(second));
}
return number;
}
1
Achintha Isuru

これは最大20桁の一意の乱数の生成を処理できます

_ js _

var generatedNumbers = [];

function generateRandomNumber(precision) { // precision --> number precision in integer 
    if (precision <= 20) {
        var randomNum = Math.round(Math.random().toFixed(precision) * Math.pow(10, precision));
        if (generatedNumbers.indexOf(randomNum) > -1) {
            if (generatedNumbers.length == Math.pow(10, precision))
                return "Generated all values with this precision";
                return generateRandomNumber(precision);
        } else {
            generatedNumbers.Push(randomNum);
            return randomNum;
        }
    } else
       return "Number Precision shoould not exceed 20";
}
generateRandomNumber(1);

enter image description here

JsFiddle

0
Nofi

/ *数字を受け取り、0からその数字までの間のランダムな整数を返すrandUpToと呼ばれる関数を書きますか? * /

var randUpTo = function(num) {
    return Math.floor(Math.random() * (num - 1) + 0);
};

/ *範囲を表す2つの数字を受け入れ、それら2つの数字の間のランダムな整数を返すrandBetweenという関数を作成します。 * /

var randBetween = function (min, max) {
    return Math.floor(Math.random() * (max - min - 1)) + min;
};

/ *範囲を表す2つの数値を受け入れ、min(両端を含む)とmax(両端を含まない)の間の乱数を返すrandFromTillという名前の関数を作成します。 * /

var randFromTill = function (min, max) {
    return Math.random() * (max - min) + min;
};

/ *範囲を表す2つの数を受け入れ、min(両端を含む)とmax(両端を含む)の間のランダムな整数を返すrandFromToという関数を作成します。* /

var randFromTo = function (min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
};
0
Prakhar Mittal

Math.random()は高速で多くの目的に適していますが、暗号的に安全な値が必要な場合(安全ではない)、あるいは完全に一様な不偏分布からの整数が必要な場合は適切ではありません。他の人よりも)。

そのような場合、crypto.getRandomValues()を使って安全な整数を生成し、一様にターゲット範囲にマッピングできない生成された値をすべて拒否することができます。これは遅くなりますが、極端に大量の値を生成しているのでなければ意味がありません。

偏った分布の懸​​念を明確にするために、1から5までの値を生成したいが、1から16までの値(4ビット値)を生成する乱数ジェネレータがある場合を考えてみましょう。同じ数の生成値を各出力値にマッピングする必要がありますが、16は5で均等に分割されません。残りの1は残ります。したがって、生成される可能性のある値を1つ拒否し、ターゲット範囲に一様にマッピングできる15個の小さい値のうちの1つ。私たちの行動はこの擬似コードのように見えるでしょう:

Generate a 4-bit integer in the range 1-16.
If we generated  1,  6, or 11 then output 1.
If we generated  2,  7, or 12 then output 2.
If we generated  3,  8, or 13 then output 3.
If we generated  4,  9, or 14 then output 4.
If we generated  5, 10, or 15 then output 5.
If we generated 16 then reject it and try again.

次のコードでも同様のロジックを使用していますが、JavaScriptの標準のnumber型で表すことができる最大の共通整数サイズであるため、代わりに32ビット整数を生成します。選択した範囲に関係なく、拒否される生成値の割合は常に0.5未満になるため、予想される拒否数は常に0.5になります。これは、BigIntsを使用するように変更できます。 1.0未満で、通常は0.0に近い。あなたはそれが永遠にループすることを心配する必要はありません。

const randomInteger = (min, max) => {
  const range = max - min;
  const maxGeneratedValue = 0xFFFFFFFF;
  const possibleResultValues = range + 1;
  const possibleGeneratedValues = maxGeneratedValue + 1;
  const remainder = possibleGeneratedValues % possibleResultValues;
  const maxUnbiased = maxGeneratedValue - remainder;

  if (!Number.isInteger(min) || !Number.isInteger(max) ||
       max > Number.MAX_SAFE_INTEGER || min < Number.MIN_SAFE_INTEGER) {
    throw new Error('Arguments must be safe integers.');
  } else if (range > maxGeneratedValue) {
    throw new Error(`Range of ${range} (from ${min} to ${max}) > ${maxGeneratedValue}.`);
  } else if (max < min) {
    throw new Error(`max (${max}) must be >= min (${min}).`);
  } else if (min === max) {
    return min;
  } 

  let generated;
  do {
    generated = crypto.getRandomValues(new Uint32Array(1))[0];
  } while (generated > maxUnbiased);

  return min + (generated % possibleResultValues);
};

console.log(randomInteger(-8, 8));          // -2
console.log(randomInteger(0, 0));           // 0
console.log(randomInteger(0, 0xFFFFFFFF));  // 944450079
console.log(randomInteger(-1, 0xFFFFFFFF));
// Error: Range of 4294967296 covering -1 to 4294967295 is > 4294967295.
console.log(new Array(12).fill().map(n => randomInteger(8, 12)));
// [11, 8, 8, 11, 10, 8, 8, 12, 12, 12, 9, 9]
0
Jeremy

私は、min、max、exclude(除外する整数のリスト)、およびseed(シードされたランダムジェネレータが欲しい場合)のようなオプションを考慮に入れるこの関数を作りました。

get_random_int = function(args={})
{
    let def_args =
    {
        min: 0,
        max: 1,
        exclude: false,
        seed: Math.random
    }

    args = Object.assign(def_args, args)

    let num = Math.floor(args.seed() * (args.max - args.min + 1) + args.min)

    if(args.exclude)
    {
        let diff = args.max - args.min
        let n = num

        for(let i=0; i<diff*2; i++)
        {
            if(args.exclude.includes(n))
            {
                if(n + 1 <= args.max)
                {
                    n += 1
                }

                else
                {
                    n = args.min
                }
            }

            else
            {
                num = n
                break
            }
        }
    }

    return num
}

それはのように使用することができます:

let n = get_random_int
(
    {
        min: 0,
        max: some_list.length - 1,
        exclude: [3, 6, 5],
        seed: my_seed_function
    }
)

もっと簡単に言うと:

let n = get_random_int
(
    {
        min: 0,
        max: some_list.length - 1
    }
)

それからあなたはすることができます:

let item = some_list[n]

要旨: https://Gist.github.com/madprops/757deb000bdec25776d5036dae58ee6e

0
madprops