Adam
Adam

Reputation: 9049

javascript getting random number from multiple ranges

I've seen different implementations for different languages, however I've yet to come across a js method.

Essentially, I want to be able to retrieve a random value within a supplied array of ranges: var ranges = [{min:2,max:50},{min:500,max:600}, etc...];

I have the basic min max function, just not sure how to efficiently do this:

function getRandomNumber(min,max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
  }

Upvotes: 1

Views: 2084

Answers (3)

EvilTak
EvilTak

Reputation: 7579

The way this method works is that each range represents a fraction of the sum total of all possible values in all the ranges. If n is the total number of all possible values, you can imagine the values in the ranges being distributed as follows:

1------10|11-----14|15---------------40|41-----49|....|(n-x)-----n
 range 1 | range 2 |       range 3     | range 4 |....|  range n

Where 1-10 corresponds to the values in range 1, and so on.

From there on it is the simple matter of generating a random number from 1 to n, figuring out which range it belongs to and which value in that range it corresponds to.

Let the ranges be represented as an array of tuples, as

ranges = [(2, 50), (500, 600), (630, 890)]

Assuming that the ranges are sorted and do not overlap each other, first we have to find the total number of integers spanning these ranges, i.e. the total number of possible values we can generate (n). We store the lengths of these ranges in an array lengths. Pseudocode:

lengths = ranges.map(range => range.max - range.min + 1)

Note that the map function specified above holds good only for inclusive ranges. Depending on the types of your ranges, you may have to change it. Also note that n = sum(lengths).

Let x be a random number in the range 1 to n (inclusive). Then the array index i of the range in which the xth integer is found is given as:

i = 0
while (x > lengths[i]) {
    x -= lengths[i]
    i++
}

After this loop, x will contain the index of the random number in range i. That is, if x is 3, the random number is the third number in range i.

The required random number is then given by ranges[i].min + (x - 1).

Upvotes: 1

Karan Singh Dhir
Karan Singh Dhir

Reputation: 751

You can use the forEach method for this. The forEach() method calls a provided function once for each element in an array, in order. Read more about forEach at: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

var ranges = [{
  min: 2,
  max: 50
}, {
  min: 500,
  max: 600
}];

ranges.forEach(function(e) {
  console.log(Math.floor((Math.random() * (e.max - e.min + 1)) + e.min));
})

Upvotes: 1

Emre A
Emre A

Reputation: 71

It's simple, you just need a for loop that iterates through all minimum and maximum values of an array and gets results from using the function you've provided:

arrRange = [
    [15, 32],
    [9, 43],
    [8, 15]
]

function getRandomNumber(min,max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

for(i = 0; i < arrRange.length; i++) {
    min = arrRange[i][0];
    max = arrRange[i][1];
    randomNumber = getRandomNumber(min, max);
    console.log("A random number between " + min + " and " + max + " is " + randomNumber);
}

Results:

A random number between 15 and 32 is 28
A random number between 9 and 43 is 17
A random number between 8 and 15 is 15

Upvotes: 0

Related Questions