运行随机数字并保持状态

我使用下面的代码从指定的范围内获得随机值

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电话,但迷路:(任何想法如何做到这一点?

一种方法是创build一个数组来存储现有select,将所选元素推送到数组,检查数组是否包含元素,以及存储值.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)); 

我的解决scheme使用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)); 

这是一个使用lodash的sampleSizepullAt的解决scheme:

 // 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]); 
 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) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script> 

你可以做如下

 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()));