i am trying to generate 5 random numbers in an array and output them, however i don't want 2 values to be the same, what do i need to add to this code to prevent this?
using System;
public class Program
{
public static void Main()
{
int count = 0;
int Randomnum=0;
int[] num = new int[5];
Random r = new Random();
while(count < 5){
Randomnum= r.Next(1,10);
num[count]=Randomnum;
count = count 1;
}
foreach(var entry in num)
{
Console.WriteLine(entry);
}
}
}
CodePudding user response:
You could get your full set using Enumerable.Range, order them by a random value and get top 5. ie:
var numberSet = Enumerable.Range(1,10);
var randomSet = numberSet.OrderBy(s => Guid.NewGuid()).Take(5);
foreach (var entry in randomSet)
{
Console.WriteLine(entry);
}
CodePudding user response:
Your current implementation could be edited so that it adds the new random value (and increments the counter) only if num
does not already contain the value.
Your variables are defined as follows:
int count = 0;
int randomNum = 0;
int[] num = new int[5];
Random r = new Random();
One way of checking whether or not num
contains the new value is by using Array.IndexOf()
. This method returns the index at which the value you provide is found in the array that you provide. If the value you provide is not found in the array, the method will return -1
.
(Note: Array.IndexOf()
specifically returns the lower bound of the array minus 1 when no match is found. Seeing as you populate num
starting at index 0
, the return value is therefore -1
in your scenario. More about the computation of an array's lower bound here).
The implementation of your while
loop could thus be adjusted to:
while (count < 5)
{
randomNum = r.Next(1, 10);
if (Array.IndexOf(num, randomNum) < 0)
{
num[count] = randomNum;
count = 1;
}
}
An alternative to using Array.IndexOf()
is to use Enumerable.Contains()
from the System.Linq namespace. I find it to be more readable, so I just thought I'd mention it.
//using System.Linq;
while (count < 5)
{
randomNum = r.Next(1, 10);
if (!num.Contains(randomNum))
{
num[count] = randomNum;
count = 1;
}
}
That being said, you may want to consider using a HashSet
rather than an array for this scenario. A HashSet
can only contain distinct values, which is what you want to achieve.
HashSet
's .Add()
method actually checks whether your HashSet
already contains the value you are trying to add. If it does, the value will not be added again.
- Due to this behavior, you can call
.Add()
for every random value that you generate, without manually having to check for existence beforehand. - Another beneficial side effect of this is that your
count
andrandomNum
variables are no longer necessary.
Using a HashSet
rather than an array, your code (prior to the code that prints the result to the console) could be implemented as follows:
//using System.Collections.Generic;
HashSet<int> num = new();
Random r = new Random();
while (num.Count < 5)
{
num.Add(r.Next(1, 10));
}
Example fiddle with all three implementations here.