Reputation: 31
how can I get two strings from two arrays randomly. I have something, but It doesn't pick randomly.
string[] firstNames = { "John", "Michael", "Victor", "Mark", "Alex", "Steven", "Zack", "Howard", "Xzavier", "Brendan", "Dustin", "Carl" };
string[] lastNames = { "Adams", "McGregor", "Piasta", "Semmel", "Laris", "Sever", "Bourque", "Percy", "Shanabarger", "Bobak", "Adair" };
string[] shuffled = firstNames.OrderBy(n => Guid.NewGuid()).ToArray();
string[] shuffled2 = firstNames.OrderBy(n => Guid.NewGuid()).ToArray();
Random firstn = new Random();
Random lastn = new Random();
int index = firstn.Next(firstNames.Length);
int index2 = lastn.Next(lastNames.Length);
Console.WriteLine($"The random name is {firstNames[index]}" + $" {lastNames[index2]}");
I am trying to make a random full name generator. I have tried this code multiple times and the results were: John Adams, Victor Piasta, and so on! And as you can see they are not random.
Upvotes: 2
Views: 860
Reputation: 63
Random works slightly different in .NET-Framework to .NET-Core
In .NET Framework, the default seed value is time-dependent. In .NET Core, the default seed value is produced by the thread-static, pseudo-random number generator.
From: https://learn.microsoft.com/en-us/dotnet/api/system.random?view=netcore-3.1#Instantiate
In the .NET-Framework only, on most Windows systems, Random objects created within 15 milliseconds of one another are likely to have identical seed values.
Use a single Random-instance on .NET-Framework to avoid this behaviour.
Upvotes: 2
Reputation: 8743
Random
does not actually generate random numbers, but pseudo-random numbers. That means, you need a starting value, the so-called seed. From that value the first number is calculated. From that, one could calculate another number, and so on. These numbers look like random, but actually they are determined by the seed. If you have the same seed, you always get the same sequence of numbers.
Your Random
class has actually a constructor where you can deliver a seed. You can try it out here: https://dotnetfiddle.net/0bHDNg For the same seed, you will always get the same sequence of numbers.
If you use the constructor without a parameter, the current time is taken as the seed. This has the big advantage, that you always get a different sequence of numbers when you restart the program. But in your example, you have a problem: If the time between creating the two instances of Random
has not changed, because the computer is so fast, they will have both the same seed and thus both the same sequence of numbers. That's why index
and index2
both have the same value. Just use the same instance of Random
for generating both indices, and they don't have necessarily the same value:
Random random = new Random();
int index = random .Next(firstNames.Length);
int index2 = random .Next(lastNames.Length);
Console.WriteLine($"The random name is {firstNames[index]}" + $" {lastNames[index2]}");
Upvotes: 1
Reputation: 4679
Just change to below so that you are using the same Random instance for both
int index2 = firstn.Next(lastNames.Length);
Upvotes: 1
Reputation: 331
Looks pretty random to me..
With 150 iterations you still get a performance of roughly 90 of 132 possible combinations.
Testing code:
HashSet<string> names = new HashSet<string>(150);
Random rndm = new Random();
for (int i = 0; i < 150; i++)
{
names.Add($"{firstNames[rndm.Next(firstNames.Length)]} " +
$"{lastNames[rndm.Next(lastNames.Length)]}");
}
Console.WriteLine($"{names.Count} / {firstNames.Length * lastNames.Length}");
Console.ReadKey();
Don't forget that true random is not possible to simulate... so you will always have some kind of repetitive distribution with higher numbers.
Upvotes: 2