EN
C#/.NET - generate unique random numbers
12
points
There is couple of ways to generate unique random numbers in C#/.NET.
1. Array with custom shuffling example
public static class RandomUtils
{
public static int[] generateUniqueNumbers(int minValue, int maxValue)
{
if (minValue > maxValue)
throw new ArgumentException("Minimal value cannot be bigger than maximal value.");
int[] values = new int[maxValue - minValue + 1];
for (int i = 0; i < values.Length; ++i)
values[i] = minValue + i;
Random random = new Random();
for (int i = 0; i < values.Length; ++i)
{
int index = random.Next(values.Length);
if (i == index)
continue;
int tmp = values[i];
values[i] = values[index];
values[index] = tmp;
}
return values;
}
}
Example:
int[] ranges = {
// min, max,
5, 15,
-4, 4
};
for(int i = 0; i < ranges.Length; i += 2)
{
int minValue = ranges[i + 0];
int maxValue = ranges[i + 1];
int[] values = RandomUtils.generateUniqueNumbers(minValue, maxValue);
Console.WriteLine("Random unique values from " + minValue + " to " + maxValue + ": ");
foreach (int entry in values)
Console.Write(entry + " ");
Console.WriteLine();
Console.WriteLine();
}
Output:
Random unique values from 5 to 15:
14 8 15 7 5 6 10 9 13 11 12
Random unique values from -4 to +4:
0 -4 4 1 -3 2 3 -1 -2
2. Array.Sort
method based example
public static class RandomUtils
{
public static int[] generateUniqueNumbers(int minValue, int maxValue)
{
if (minValue > maxValue)
throw new ArgumentException("Minimal value cannot be bigger than maximal value.");
int[] values = new int[maxValue - minValue + 1];
for (int i = 0; i < values.Length; ++i)
values[i] = minValue + i;
Random random = new Random();
Array.Sort(values, (a, b) => random.Next(-1, 2));
return values;
}
}
Example:
int[] ranges = {
// min, max,
5, 15,
-4, 4
};
for(int i = 0; i < ranges.Length; i += 2)
{
int minValue = ranges[i + 0];
int maxValue = ranges[i + 1];
int[] values = RandomUtils.generateUniqueNumbers(minValue, maxValue);
Console.WriteLine("Random unique values from " + minValue + " to " + maxValue + ": ");
foreach (int entry in values)
Console.Write(entry + " ");
Console.WriteLine();
Console.WriteLine();
}
Output:
Random unique values from 5 to 15:
6 5 7 10 8 11 9 12 13 14 15
Random unique values from -4 to 4:
-3 -4 -2 1 -1 0 4 2 3
3 Enumerable.Range
+ Enumerable.OrgedBy
methods based example
public static class RandomUtils
{
public static int[] generateUniqueNumbers(int minValue, int maxValue)
{
if (minValue > maxValue)
throw new ArgumentException("Minimal value cannot be bigger than maximal value.");
Random random = new Random();
int[] values = Enumerable.Range(minValue, maxValue - minValue + 1)
.OrderBy((a) => random.Next(-1, 2))
.ToArray();
return values;
}
}
Example:
int[] ranges = {
// min, max,
5, 15,
-4, 4
};
for(int i = 0; i < ranges.Length; i += 2)
{
int minValue = ranges[i + 0];
int maxValue = ranges[i + 1];
int[] values = RandomUtils.generateUniqueNumbers(minValue, maxValue);
Console.WriteLine("Random unique values from " + minValue + " to " + maxValue + ": ");
foreach (int entry in values)
Console.Write(entry + " ");
Console.WriteLine();
Console.WriteLine();
}
Output:
Random unique values from 5 to 15:
5 7 8 9 11 13 14 6 10 12 15
Random unique values from -4 to 4:
-3 0 -2 -1 1 2 4 -4 3
4. HashSet
class based example
public static class RandomUtils
{
public static int[] generateUniqueNumbers(int minValue, int maxValue)
{
if (minValue > maxValue)
throw new ArgumentException("Minimal value cannot be bigger than maximal value.");
Random random = new Random();
HashSet<int> values = new HashSet<int>(maxValue - minValue + 1);
for (int i = minValue; i < maxValue;)
{
int value = random.Next(minValue, maxValue + 1);
if(values.Add(value))
i += 1;
}
return values.ToArray();
}
}
Example:
int[] ranges = {
// min, max,
5, 15,
-4, 4
};
for(int i = 0; i < ranges.Length; i += 2)
{
int minValue = ranges[i + 0];
int maxValue = ranges[i + 1];
int[] values = RandomUtils.generateUniqueNumbers(minValue, maxValue);
Console.WriteLine("Random unique values from " + minValue + " to " + maxValue + ": ");
foreach (int entry in values)
Console.Write(entry + " ");
Console.WriteLine();
Console.WriteLine();
}
Output:
Random unique values from 5 to 15:
5 14 8 11 10 12 9 13 7 6
Random unique values from -4 to 4:
1 -4 -2 2 3 0 -1 -3
Note: generating random unique values with HashSet
could take in most worse case much more iterations than number of expected numbers.