JavaScript的 - 如何随机样本项目,而不更换?(JavaScript - How to r

2019-07-01 11:15发布

JavaScript的

我试图寻找这样的事情,但我没能找到它。

这是一个简单的想法:

一个。 取0之间的随机数为10。

湾 比方说推出的随机数是3。

C。 然后,保存号(3)。

d。 现在,再取另一个随机数0至10人之间,但它不能是3,因为它已经出现了。

Answer 1:

一种解决方案是与所有要挑值以产生一个阵列(一“桶”),在这种情况下从0到10的所有数字。然后从该阵列选择一个随机和从桶中取出。 请注意,下面的例子不检查水桶是空的,所以如果你可以拨打下面的10倍以上的功能,你会得到一个错误。

var bucket = [];

for (var i=0;i<=10;i++) {
    bucket.push(i);
}

function getRandomFromBucket() {
   var randomIndex = Math.floor(Math.random()*bucket.length);
   return bucket.splice(randomIndex, 1)[0];
}

// will pick a random number between 0 and 10, and can be called 10 times
console.log(getRandomFromBucket());


Answer 2:

其中RND = getRnd();

虽然(!RND = lastRnd)RND = getRnd();

其中getRnd是产生你的随机数的函数。

事实上,你必须检查,如果你当前的随机数是在一个数组...如果你可以随机数的列表很小提防无限循环的。



Answer 3:

您可以使用这样的事情:

/**
* range Get an array of numbers within a range
* @param min {number} Lowest number in array
* @param max {number} Highest number in array
* @param rand {bool} Shuffle array
* @return {array}
*/
range: function( min, max, rand ) {
  var arr = ( new Array( ++max - min ) )
    .join('.').split('.')
    .map(function( v,i ){ return min + i })
  return rand
    ? arr.map(function( v ) { return [ Math.random(), v ] })
       .sort().map(function( v ) { return v[ 1 ] })
    : arr
}

并使用它像这样:

var arr = range( 1, 10, true )

现在你有一个从110个号码10以随机顺序和从不重复的数组。 所以,下次你可以这样做:

arr.forEach(function( num, i ) { 
  // do something, it will loop 10 times 
  // and num will always be a different number
  // from 1 to 10
});


Answer 4:

只是为了好玩:从@衍生Strilles回答“斗构造”

function RandomBucket(from,until){
  min = (Number(from) || 0);
  max = (Number(until) || 10)+1;
  this.bucket = String(Array(max-min)).split(',').map(function(i){
     return min++;
  });

  if (!RandomBucket.prototype.get){
   RandomBucket.prototype.get = function(){
      var randomValue = 
        this.bucket.length < 2
        ? this.bucket.shift()
        : this.bucket.splice(Math.floor(Math.random()*this.bucket.length),1);
       return randomValue || 'bucket empty';
      };
  }
}

的jsfiddle的使用示例



Answer 5:

使用D3 :

var bucket = d3.shuffle(d3.range(11));

while(bucket.length) {
  console.log(bucket.pop());
}


Answer 6:

大部分时间我会通过其他的答案提出的方法坚持 - 即创建一系列的可能,创造它的改组型式,然后在第n个值作为样本(即简单,一般都可以操作被一成不变实现)。

然而,这不是巨大的,如果可能性的范围较大时相比,你要多少内存来使用,或比你想画(虽然@Strilles解决方案使用的内存多少随机值,但不会吸引很多随机值,因此可能甚至低于我的用例)是最好的。

沿着你的问题似乎暗示可能看起来像这样的线A的解决方案:

// select n integers from the range [from, to] (inclusive at both sides),
// don't use this approach for large values of n
// taking random values from the randomSource as needed
function randomNumbersWithoutReplacement(n, from, to, randomSource = Math.random) {
    const result = [];
    for (let i = 0; i < n; ++i) {
        // i values have already been taken
        // the +1 makes it inclusive
        const rangeWidth = to - from - i + 1

        let value = Math.floor(rangeWidth * randomSource()) + from

        // correct the value compared to the already sampled integers
        for (let j = 0; j < result.length; ++j) {
            if (result[j] <= value) {
                value++
            }
        }

        result.push(value)

        // sorting makes the correction loop simpler
        // (and it's nice to report the result sorted too)
        result.sort((a, b) => a - b)
    }
    return result
}

你为什么可能要这样?

const quantumLottoNumbers = randomNumbersWithoutReplacement(6, 1, 59, quantumRandomSource)


文章来源: JavaScript - How to randomly sample items without replacement?