Generating Unique Random Numbers In JavaScript Using Sets
JavaScript comes with a lot of built-in functions that allow you to carry out so many different operations. One of these built-in functions is the `Math.random()` method, which generates a random floating-point number that can then be manipulated into integers.
However, if you wish to generate a series of unique random numbers and create more random effects in your code, you will need to come up with a custom solution for yourself because the `Math.random()` method on its own cannot do that for you.
In this article, we’re going to be learning how to circumvent this issue and generate a series of unique random numbers using the `Set` object in JavaScript, which we can then use to create more randomized effects in our code.
**Note**: _This article assumes that you know how to generate random numbers in JavaScript, as well as how to work with sets and arrays._
Generating a Unique Series of Random Numbers
One of the ways to generate a unique series of random numbers in JavaScript is by using `Set` objects. The reason why we’re making use of sets is because the elements of a set are unique. We can iteratively generate and insert random integers into sets until we get the number of integers we want.
And since sets do not allow duplicate elements, they are going to serve as a filter to remove all of the duplicate numbers that are generated and inserted into them so that we get a set of unique integers.
Here’s how we are going to approach the work:
1. Create a `Set` object.
2. Define how many random numbers to produce and what range of numbers to use.
3. Generate each random number and immediately insert the numbers into the `Set` until the `Set` is filled with a certain number of them.
The following is a quick example of how the code comes together:
```
function generateRandomNumbers(count, min, max) {
// 1: Create a Set object
let uniqueNumbers = new Set();
while (uniqueNumbers.size < count) {
// 2: Generate each random number
uniqueNumbers.add(Math.floor(Math.random() * (max - min + 1)) + min);
}
// 3: Immediately insert them numbers into the Set...
return Array.from(uniqueNumbers);
}
// ...set how many numbers to generate from a given range
console.log(generateRandomNumbers(5, 5, 10));
```
What the code does is create a new `Set` object and then generate and add the random numbers to the set until our desired number of integers has been included in the set. The reason why we’re returning an array is because they are easier to work with.
One thing to note, however, is that the number of integers you want to generate (represented by `count` in the code) should be less than the upper limit of your range plus one (represented by `max + 1` in the code). Otherwise, the code will run forever. You can add an `if statement` to the code to ensure that this is always the case:
```
function generateRandomNumbers(count, min, max) {
// if statement checks that count is less than max + 1
if (count > max + 1) {
return "count cannot be greater than the upper limit of range";
} else {
let uniqueNumbers = new Set();
while (uniqueNumbers.size < count) {
uniqueNumbers.add(Math.floor(Math.random() * (max - min + 1)) + min);
}
return Array.from(uniqueNumbers);
}
}
console.log(generateRandomNumbers(5, 5, 10));
```
Using the Series of Unique Random Numbers as Array Indexes
It is one thing to generate a series of random numbers. It’s another thing to use them.
Being able to use a series of random numbers with arrays unlocks so many possibilities: you can use them in shuffling playlists in a music app, randomly sampling data for analysis, or, as I did, [shuffling the tiles in a memory game](https://github.com/jimavictor/remoji).
Let’s take the code from the last example and work off of it to return random letters of the alphabet. First, we’ll construct an array of letters:
```
const englishAlphabets = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
];
// rest of code
```
Then we `map` the letters in the range of numbers:
```
const englishAlphabets = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
];
// generateRandomNumbers()
const randomAlphabets = randomIndexes.map((index) => englishAlphabets[index]);
```
In the original code, the `generateRandomNumbers()` function is logged to the console. This time, we’ll construct a new variable that calls the function so it can be consumed by `randomAlphabets`:
```
const englishAlphabets = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
];
// generateRandomNumbers()
const randomIndexes = generateRandomNumbers(5, 0, 25);
const randomAlphabets = randomIndexes.map((index) => englishAlphabets[index]);
```
Now we can log the output to the console like we did before to see the results:
```
const englishAlphabets = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
];
// generateRandomNumbers()
const randomIndexes = generateRandomNumbers(5, 0, 25);
const randomAlphabets = randomIndexes.map((index) => englishAlphabets[index]);
console.log(randomAlphabets);
```
And, when we put the `` generateRandomNumbers` ``()\` function definition back in, we get the final code:
```
const englishAlphabets = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
];
function generateRandomNumbers(count, min, max) {
if (count > max + 1) {
return "count cannot be greater than the upper limit of range";
} else {
let uniqueNumbers = new Set();
while (uniqueNumbers.size < count) {
uniqueNumbers.add(Math.floor(Math.random() * (max - min + 1)) + min);
}
return Array.from(uniqueNumbers);
}
}
const randomIndexes = generateRandomNumbers(5, 0, 25);
const randomAlphabets = randomIndexes.map((index) => englishAlphabets[index]);
console.log(randomAlphabets);
```
So, in this example, we created a new array of alphabets by randomly selecting some letters in our `englishAlphabets` array.
You can pass in a count argument of `englishAlphabets.length` to the `generateRandomNumbers` function if you desire to shuffle the elements in the `englishAlphabets` array instead. This is what I mean:
```
generateRandomNumbers(englishAlphabets.length, 0, 25);
```
Wrapping Up
In this article, we’ve discussed how to create randomization in JavaScript by covering how to generate a series of unique random numbers, how to use these random numbers as indexes for arrays, and also some practical applications of randomization.
The best way to learn anything in software development is by consuming content and reinforcing whatever knowledge you’ve gotten from that content by practicing. So, don’t stop here. Run the examples in this tutorial (if you haven’t done so), play around with them, come up with your own unique solutions, and also don’t forget to share your good work. Ciao!
https://smashingmagazine.com/2024/08/generating-unique-random-numbers-javascript-using-sets/