3

When I call this statement 4 times in a loop, it gives me duplicate random numbers.

var a = (parseInt(Math.random() * 4))+1

For example, sometimes it gives me 1,3,2,4 (fine!!), but sometimes it produes like 1, 3, 1,4 etc.

How I make sure that when my loop runs 4 times, I get unique set everytime

gkalpak
  • 47,844
  • 8
  • 105
  • 118
  • 1
    Loop until you don't have duplicates. – ComFreek Oct 19 '13 at 13:18
  • store them in an array and validate your function's out put against the "seen before" values. – Hedde van der Heide Oct 19 '13 at 13:19
  • The reason it is called "random" is because it generates (sort of) random numbers. There is no guarantee that they are going to be unique. – gkalpak Oct 19 '13 at 13:20
  • So you have a collection of numbers which you want to have in a random order? – t.niese Oct 19 '13 at 13:22
  • 1
    don't loop until there are no duplicates anymore. This loop possibly runs forever. If you get a duplicate number N you could possibly just take the N+1 number or the N+2 if also N+1 is a duplicate and so on.... – JanUlrich Oct 19 '13 at 13:27
  • @JanUlrich The probability that the code will loop forever is very, very low! Math.random() doesn't even return a real random number. – ComFreek Oct 19 '13 at 13:29
  • Just for clarification - computers (and thus functions for random number generation in every programming language including JavaScript) can generate only [pseudorandom numbers](http://en.wikipedia.org/wiki/Pseudorandom_number_generator). – keenthinker Oct 19 '13 at 13:29
  • If the only requirement for numbers is to be unique, add each generated number to the previous + 1 . If you have a set of numbers and need then to be random shuffled, put them in array and shuffle the array. – MC ND Oct 19 '13 at 13:51

6 Answers6

4

Shuffling a pre-filled array would be a good solution:

→ jsBin.com

// shuffle function taken from here
// http://stackoverflow.com/a/2450976/603003
alert( shuffle( [1,2,3,4] ) );

Another apporach consists in the following function:

→ jsFiddle

function gen4Numbers() {
    var numbers = [];
    while (numbers.length < 4) {
        var newNr = (parseInt(Math.random() * 4))+1;
        if (numbers.indexOf(newNr) == -1) {
            numbers.push(newNr);
        }
    }
    return numbers;
}
alert(gen4Numbers());

You should be warned that there is a very probability that this code will loop forever.

ComFreek
  • 29,044
  • 18
  • 104
  • 156
4

You need to buffer your answers, but a much better way is to pre-compute them.

So for example you want random integers from 1 to 4 and unique, this is the same thing as randomly sorting an array of values from 1 to 4

for the general case:

// numbers of values
var n = 10;

// make initially sorted array
var arr = [];
for (var i=1; i<=n; ++i) { arr.push(i); }

// randomly sort the array
arr.sort(function () { return Math.random() - 0.5; });

now arr will have all the numbers from 1 to 10 in a random order, so if you want 4 unique random numbers in that range they are in arr[0], arr[1] arr[2], arr[3]

make n = 4 and you have your problem solved

Stefan
  • 3,962
  • 4
  • 34
  • 39
2

i am using time

var d = new Date(); 
var uniqId = d.getTime();
Yoav B
  • 27
  • 5
1

Store the numbers in an array, and each time check if the number was generated before.

If you aren't generating a lot of numbers, this is pretty fast since you don't have to

loop a lot.

============= Edit 1 =============

However, if you have to generate a lot of random numbers, I suggest putting an array of

all the numbers, shuffling it, and then taking the first n numbers that you need.

Array shuffling can be found here:

http://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
Se Won Jang
  • 773
  • 1
  • 5
  • 12
0

In case you want a huge set of numbers, you should store every distinct number, then pick one up every iteration of the loop.

var maxnB = 1000; // or 4
var list = [];

for (var i = 1; i <= maxNb; ++i) // store all number in a list [1, 2, 3, ... , maxNb]
   list.push(i);

while (list.length > 0)
{
   var pos = (parseInt(Math.random() * list.length))

   var myNumber = list[pos];  // get your unique random number
   list[pos] = list[list.length - 1]; // replace the number used with last number 
   list.pop(); //remove last number, decrease list.length by 1

   // do something with your new number
}

Doing this, you have a 0 probability of looping forever, and if the pop() method and [] operator has a o(1) time complexity access, it will improve the time processing, instead of looking for your number in the buffer list every time you got a new number to check.

Marcassin
  • 1,386
  • 1
  • 11
  • 21
0

do this.

for( i = 0; i< 4; i++)
{
  num = Math.floor((Math.random() * 3) + 1);

  if(randomArray.indexOf(num)<0)
  {
    randomArray[i]=num;
  }//endif
  else
  {
    i=i-1;
  }//endElse
}//endForLoop

basically, if a number is repeated -lets say at position 3 (randomArray[3] has same value as randomArray[atAnotherIndex], your counter goes back to 3 and do math.random again until a unique value is attained.