## DEV Community is a community of 850,636 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

# Generate unique (non-repeating) random numbers

Backstory: when I was doing one of my side projects, one of the tasks was to display photos from Unspash API in multiple cards. Goal was to pick photos randomly without repeating them. I used good old `Math.random()` to randomly pick photos from API's response. But the problem was that often few numbers were repeating, thus there were the same pictures in different cards.

Let's say you want to generate 5 random unique numbers from 1 to 10. Big chances that you'll get at least one repeated number.

Solution for this task is to replace each picked (random) number in array with another unused one.

In the code this would be something like this:

``````function randomUniqueNum(range, outputCount) {

let arr = []
for (let i = 1; i <= range; i++) {
arr.push(i)
}

let result = [];

for (let i = 1; i <= outputCount; i++) {
const random = Math.floor(Math.random() * (range - i));
result.push(arr[random]);
arr[random] = arr[range - i];
}

return result;
}
``````

Let's look line by line.
Function takes range, and output count.
For instance `randomUniqueNum(10, 5)`
First we generate array from 1 to 10

`````` let arr = []
for (let i = 1; i <= 10; i++) {
arr.push(i)
}
``````

`arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]`

Then we use another loop to pick numbers from this array.
Iterations in this loop equals to output count, in this case to 5.
Then we generate random number:

``````const random = Math.floor(Math.random() * (range - i))
``````

Each iteration we decreasing range by 1.
Then using this random number as index in `arr` we push it to the result array:

``````result.push(arr[random])
``````

After that we replace 'used' number in `arr` with the one from the end of the same array:

``````arr[random] = arr[range - i]
``````

Even though in the next iteration `Math.random()` will give us the same number, we'll get different result because we replaced it with the number from the end.

Since we decrease range in each iteration: `range - i` so numbers from upper end of array will not be picked.
At the end we just return array of unique random numbers.

## Discussion (2) Nice. Here's another implementation using a `Set()`

``````const randomUnique = (range, count) => {
let nums = new Set();
while (nums.size < count) {
nums.add(Math.floor(Math.random() * (range - 1 + 1) + 1));
}
return [...nums];
}
``````