运行随机数并保持状态

时间:2016-12-06 17:13:17

标签: javascript node.js algorithm ecmascript-6 lodash

我使用以下代码从指定的范围中获取随机值

var provideRanges = function(){
    var aa = [];
    _.times(3, function(i) {
      console.log(i);
      let num = _.random(10, 20)
      console.log("num = :" + num)
      debugger;
      aa.push(num);
      console.log("value is :" + aa[i]);
    });
}

这是有效的,当你调用这个函数时,在指定的范围之间提供3个值的数组,但是如果我再次调用它,那么这里的问题变得更加困难忽略排除上一个从提供的数字中提供的数字(如果下次不提供这些数字时提供10,11,12 ......),有没有更好的方法呢?我尝试使用recoursive调用但迷路:(,任何想法怎么做?

4 个答案:

答案 0 :(得分:4)

一种方法是创建一个数组来存储现有选择,将所选元素推送到数组,检查数组是否包含该元素,以及存储值.length的数组是否大于或等于最大范围减去最小范围。

从问题的描述中不清楚,一旦归还了范围内的所有元素,应该发生什么?



var range = [10, 20];
var not = [];

function randomRange(range, n) {
  if (not.length >= range[1] - range[0]) {
    return "all numbers in range used"
  }
  var curr = [];
  var res = [];
  for (let i = range[0]; i < range[1]; i++) {
    if (!not.some(function(num) {
      return i == num
    }) && not.length < range[1] - range[0]) {
      curr.push(i)
    }
  }
  for (let i = 0; i < n; i++) {
    var j = curr.splice(Math.floor(Math.random() * curr.length), 1)[0];
    res[i] = not[not.length] = j;
  }

  return res.filter(Boolean)
}

console.log(randomRange(range, 3));
console.log(randomRange(range, 3));
console.log(randomRange(range, 3));
console.log(randomRange(range, 3));
console.log(randomRange(range, 3));
&#13;
&#13;
&#13;

答案 1 :(得分:2)

我的解决方案使用Set来保留值的唯一性:

const getRangeRandomizer = ([min, max]) => { // create the range randomizer
  const state = new Set(); // the numbers that were produced from the range
  
  /** the returned method can be used to get more numbers from the range **/
  return (numOfRandoms) => {
    const discarded = new Set(); // this Set is used to count numbers that are not unique
    const range = max - min + 1;
    const result = [];
    let i = 0;
    let randNum;

    while (i < numOfRandoms && discarded.size < range) { // if we added numOfRandoms times or we discarded delta optionsm the loop end - this prevents endless loops
      randNum = Math.floor(Math.random() * (range) + min);

      if (state.has(randNum)) {
        discarded.add(randNum);
      } else {
        state.add(randNum);
        result.push(randNum);
        i++;
      }
    }

    return result;
  }
}

const provideRanges = getRangeRandomizer([10, 20]); // create a range randomizer

console.log(provideRanges(4));
console.log(provideRanges(3));
console.log(provideRanges(2));
console.log(provideRanges(4)); // only 2 results will be provided, because the rest were used

const provideOtherRanges = getRangeRandomizer([15, 20]);  // create a range randomizer
console.log(provideOtherRanges(100));

答案 2 :(得分:1)

以下是使用lodash sampleSizepullAt的解决方案:

// numbers = [10, 11, ... 19]
let numbers = _.range(10, 20);

// sampleSize will return an array containg the numbers randomized
let sample = _.sampleSize(numbers, numbers.length)

// get the first 3 numbers from the sample (pullAt will mutate sample)
let first3 = _.pullAt(sample, [0,1,2]);

// get the next 3 numbers etc.
let next3 = _.pullAt(sample, [0,1,2]);

&#13;
&#13;
let numbers = _.range(10, 20);

let sample = _.sampleSize(numbers, numbers.length)

let sample1 = _.pullAt(sample, [0,1,2]);
let sample2 = _.pullAt(sample, [0,1,2]);
let sample3 = _.pullAt(sample, [0,1,2]);
let sample4 = _.pullAt(sample, [0,1,2]);


console.log(sample1)
console.log(sample2)
console.log(sample3)
console.log(sample4)
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>
&#13;
&#13;
&#13;

答案 3 :(得分:0)

您可以执行以下操作

&#13;
&#13;
function RandomSomething(n,m){
  this.choices = new Array(n).fill().map((_,i) => i+m);
}

RandomSomething.prototype.randomFromRange = function(){
                                              return new Array(3).fill()
                                                                 .map(function(r,i){
                                                                        r = this.choices.length > 3 ? this.choices
                                                                                                          .splice(Math.floor((Math.random()*this.choices.length)),1)[0]
                                                                                                    : this.choices[i];
                                                                        return r;
                                                                      }.bind(this));
                                            };

var obj = new RandomSomething(10,100); // generate randoms at range 100-109
console.log(JSON.stringify(obj.randomFromRange()));
console.log(JSON.stringify(obj.randomFromRange()));
console.log(JSON.stringify(obj.randomFromRange()));
console.log(JSON.stringify(obj.randomFromRange()));
console.log(JSON.stringify(obj.randomFromRange()));
&#13;
&#13;
&#13;