2

I want to generate atleast 1000 unique random numbers with 10 digit using javascript in a loop. Is this possible? Or is Javascript a wrong thing to do this?

UPDATE: How will you be sure that duplicates are not created?

esafwan
  • 17,311
  • 33
  • 107
  • 166

5 Answers5

3

Here's how I would do it:

var arr = [],
    track = [],
    min = 1000000000,
    max = 9999999999,
    qty = 1000,
    ii = 0,
    rnd;

while (ii < qty) {
    rnd = Math.floor(Math.random() * (max - min + 1)) + min;
    if (!track[rnd]) {
        arr[ii] = track[rnd] = rnd;
        ii += 1;
    }
}

Here's a working example: http://jsfiddle.net/mTmEs/

Now, if something went awry with Math.random and for some reason it were to generate a lot of duplicates, this code could take a long time to complete. I don't think there is any way around this kind of potential problem though when you're talking about large quantities of unique random numbers.

FishBasketGordo
  • 22,904
  • 4
  • 58
  • 91
  • 1
    I would change track to an Object, now track is an array with an AWFUL lot of elements. Using an object will be faster. – Creynders Apr 06 '12 at 12:14
  • 1
    Your method in my test takes 8-9 msec, using one array with a loop to check for duplicates takes 40-50 msec, and using an object and recovering an array of 10 digit numbers from it takes 90+ msec. – kennebec Apr 06 '12 at 15:28
  • 1
    @Creynders: The way Fish is using the array, it's exactly the same as using a non-array object; no speed difference. He/she isn't using the array-ish-ness of it at all, and of course, JavaScript arrays [are just objects](http://blog.niftysnippets.org/2011/01/myth-of-arrays.html), not really arrays. – T.J. Crowder Apr 06 '12 at 16:16
  • 1
    @T.J.Crowder you're quite right, just did a small test and there's no substantial speed difference. I stand corrected. – Creynders Apr 06 '12 at 17:08
2

Yes, it's possible.

  1. Use Math.random to generate the pseudo-random numbers. Math.random returns a pseudo-random number greater than or equal to 0 and less than 1, so to get a 10-digit number (I'm assuming a whole number), you'd multiple that by 1,000,000,000 and round it off with Math.round or Math.floor. (If you need them all to be 10 digits, adjust accordingly — adding a base amount, multiplying by a higher number, etc.)

  2. Use an object to keep track of them, so var obj = {}; to start with.

  3. Store the numbers as keys in an object, e.g. obj[number] = true.

  4. Test whether the object has the generated number using if (obj[number])

  5. Loop until you have the correct number of unique numbers.

The reason I use an object for storing the numbers is that JavaScript objects are maps by their nature, and engines are optimized to retrieve properties from objects quickly. Under the covers, an implementation can do what it likes, but will probably use a hash table or similar.

Note that using an "array" for this is unnecessary; JavaScript arrays aren't really arrays, they're just objects with a couple of special features.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 3
    multiplying with 1,000,000,000 does not guarantee 10 digit number – Balaswamy Vaddeman Apr 06 '12 at 11:45
  • 2
    @Balaswamyvaddeman: I assumed he meant 10 digits *or less*. (Your downvote, or someone else's? Seems rather strong for such a small flaw.) – T.J. Crowder Apr 06 '12 at 12:27
  • I'd agree that 10-digit numbers included the smaller numbers that would be padded with 0s on the left. I guess it comes down to whether you consider 01 a two-digit number. – nycdan Apr 06 '12 at 12:36
1

You could do this in JS, but you would have to check the array to see if it contains the currently generated random number. This would obviously degrade performance.

See if these answers help.

Random number generator that fills an interval

Generate unique random numbers between 1 and 100

Community
  • 1
  • 1
Chris Gessler
  • 22,727
  • 7
  • 57
  • 83
1

A generic function for generating n random numbers of length l might be:

// Generate n unique random numbers of length l
// l should be less than 15
function genNRandLen(n, l) {

  // Make sure l and n are numbers
  n = Number(n);
  l = Number(l);

  // Protect against bad input
  if (isNaN(l) || isNaN(n)) return;

  var o = {}, a = [], num;
  var min = l == 1? 0 : Math.pow(10, l-1);
  var r = Math.pow(10, l) - min;

  // Protect against endless loop
  if (n >= (r)) return;

  while (n--) {
    do {
      num = Math.floor(min + (Math.random()*r));
    } while (o[num])

    o[num] = true;
    a[n] = num;
  }
  return a.sort();
}

Sorting is just to make it easy to see duplicates when testing, remove if not necessary or random order is preferred.

If numbers longer than 15 digits are required, they can be created by concatenating strings of shorter random numbers and trimming to the required length. The following will generate a random number of any length:

// Generate random number of length l
function randLen(l) {
  var n = '';
  while (n.length < l) {
    n += String(Math.random()).replace(/^0\.0*/,'');
  }
  return n.substring(0, l);
}

It must return a string since converting to number will mess with the results. Oh, and all numbers are integers.

RobG
  • 142,382
  • 31
  • 172
  • 209
-2

Why not? Here is the code:

var a=[]; 
for (var i=1000; i--;) 
 a.push(Math.random()*10000000000)
Roman Pominov
  • 1,403
  • 1
  • 12
  • 17