How can I generate a random number within a range but exclude some?

▼魔方 西西 提交于 2019-11-28 09:57:02

Set an array with all the values (this is only a valid option if you're only doing small numbers, like the 25 in your example), like this:

var array = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24];

then, pick a random number between 0 and the array length:

var num = Math.floor(Math.random() * array.length);

remove that index number from the array:

var roll = array.splice(num, 1);

Javascript splice() removes indexed items from an array and returns the item(s) as an array. Perfect for your use.

Grab the first index from the roll, since we only cut 1 out anyway:

var yourNumber = roll[ 0 ];

Keep doing for as many rolls as you want. Also, you might want to store the original array as a copy so that you can "reset" the numbers easily.

This is easy guys. You do not want recursion for this one. These answers are really bad. Ideally you do not want to hardcode the array, either.

function getRandomWithOneExclusion(lengthOfArray,indexToExclude){

  var rand = null;  //an integer

    while(rand === null || rand === indexToExclude){
       rand = Math.round(Math.random() * (lengthOfArray - 1));
    }

  return rand;
}

now use the value returned from the above function to choose an element from whatever array you want, just like so:

var arr = [];
var random = getRandomWithOneExclusion(arr.length,5);  //array has length x, we want to exclude the 5th element
var elem = arr[random];

that's it. if you wanted to exclude more than value, then you would have to make this more sophisticated, but for excluding one value, this works well. A recursive solution for this is overkill and a bad idea.

I haven't tested this, but to exclude more than one element, try this:

function getRandomWithManyExclusions(originalArray,arrayOfIndexesToExclude){

   var rand = null;

   while(rand === null || arrayOfIndexesToExclude.includes(rand)){
         rand = Math.round(Math.random() * (originalArray.length - 1));
    }
     return rand;
  }

The above method does not sound too different from the OP's original method. This method works properly because it does not sample in a biased way from the array.

Hmz :-? Fastest way to randomly get items from an array and ensure they're all unique would be:

var array = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24];

Array.prototype.shuffle = function shuffle(){
    var tempSlot;
    var randomNumber;
    for(var i =0; i != this.length; i++){
        randomNumber = Math.floor(Math.random() * this.length);
        tempSlot = this[i]; 
        this[i] = this[randomNumber]; 
        this[randomNumber] = tempSlot;
    }
}

while(array.length!=0){
    array.shuffle();
    alert(array.pop());    
}

I'm sure there are a few ways to do this, but you could put all the numbers into something like a stack, jumble it all up and then pop off of it to get your random numbers. Or, randomly seek into it every time and remove it from the stack.

step 1> create an array CHECK_ARRAY fill the array with value which is out of the range of your random number [fill it with 26 if you want to generate number within 0-25]

step2-> generate a random number and add it to RANDOM_ARRAY and also add it to the CHECK_ARRAY that is

i=0;
CHECK_ARRAY[i]=random;
i++;

step3-> generate a new random number and go though the CHECK_ARRAY, if you found 26 then ignore, else if you found duplicate then re-generate a random number and continue step 3 again until you found an unique random number !

Here is a tested and simple solution:

var array= [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24];
var random_value; 
var index;
var shuffled_array = new Array(24);

for (var i = 0; i < 24; i++) { 
random_value = array[Math.floor(Math.random()*array.length)]; //Returns a value between 1 and 24
index = array.indexOf(random_card); //Gets the index of the choosen random value
array.splice(index, 1); //Go to index of that array and remove it
shuffled_array [i] = random_value; //Put that value in a new array

window.alert("array: "+array+"\n"+"random_value: "+random_value+"\n"+"shuffled_array: "+shuffled_array);
}

In other solutions i believe they forgot to search for the index.

<div id="number" style="color: red; margin-left: 200px;">array</div>
<div id="arr" style="color: red; margin-left: 200px;">length</div>
<script>
  var arrayOfIndexesToExclude = new Array();
  function getRandomWithManyExclusions(){
    var rand = null;
      
		  	do{
		    	rand = Math.round(Math.random() * ( 9));
		    	if(arrayOfIndexesToExclude.length >= 10){
		 			  arrayOfIndexesToExclude.length = 0;	   			
		    	}
				}while(arrayOfIndexesToExclude.includes(rand));
			
			arrayOfIndexesToExclude.push(rand);  
    
    document.getElementById("number").innerHTML = arrayOfIndexesToExclude;
    document.getElementById("arr").innerHTML = arrayOfIndexesToExclude.length;
  }
</script>

Suppose you need to choose a random number from the range 1...5 and exclude the values 2, 4 then:

  • Pick a random number from the range 1...3
  • Sort excluded number list
  • For each excluded number less than the random number: add one to the random number

function getRandomExcept(min, max, except) {
  except.sort(function(a, b) {
    return a - b;
  });
  var random = Math.floor(Math.random() * (max - min + 1 - except.length)) + min;
  var i;
  for (i = 0; i < except.length; i++) {
    if (except[i] > random) {
      break;
    }
    random++;
  }
  return random;
}

/*
 * Test iterations. Make sure that:
 * excluded numbers are skipped 
 * numbers are equally distributed
 */
(function(min, max, except) {
  var iterations = 1000000;
  var i;
  var random;
  var results = {};
  for (i = 0; i < iterations; i++) {
    random = getRandomExcept(min, max, except);
    results[random] = (results[random] || 0) + 1;
  }
  for (random in results) {
    console.log("value: " + random + ", count: " + results[random] + ", percent: " + results[random] * 100 / iterations + "%");
  }
})(1, 5, [2, 4]);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!