D0WN70AD
D0WN70AD

Reputation: 31

How can I get two random strings from two arrays in C#

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

Answers (4)

Luciox
Luciox

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

SomeBody
SomeBody

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

Tim Rutter
Tim Rutter

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

Purity
Purity

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.

Output

Upvotes: 2

Related Questions