Chris Hadfield
Chris Hadfield

Reputation: 524

Get a random list of integer array in C#

public static List<int> GetRandom()
{
    Random rnd = new Random();
    List<int> list = new List<int>();

    while (list.Count <= 26)
    {
        int randomNumber = rnd.Next(1, 26);

        if (!list.Contains(randomNumber))
        {
            list.Add(randomNumber);
        }
    }

    return list;
}

This is a code where I have tried to get a random list of integer(from 1 to 26) but this doesn't return me the desired result. Here I want a random int array without any repeat.

Upvotes: 0

Views: 5750

Answers (4)

Johnny
Johnny

Reputation: 9529

Actually, you want to randomize the range of integers. You could do this using System.Linq

Random rnd = new Random();
Enumerable.Range(1, 27).OrderBy(_ => rnd.Next())

.NET Fiddle


I even measure and compare two solutions using BenchmarkDotNet, even though I was pretty sure, just as confirmation. Two scenarios have been measured, the original and one with 1000 random elements. You could see performance degradation if you increase the number of the elements(which is logical as with the increase of the number of the elements you have an even higher probability to have the collision).

BenchmarkDotNet=v0.11.5, OS=Windows 7 SP1 (6.1.7601.0)
Intel Core i7-6700 CPU 3.40GHz (Skylake), 1 CPU, 8 logical and 4 physical cores
Frequency=3328320 Hz, Resolution=300.4519 ns, Timer=TSC
[Host]     : .NET Framework 4.6.2 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.2650.0
DefaultJob : .NET Framework 4.6.2 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.2650.0

n=26

| Method |     Mean |     Error |    StdDev | Rank |
|------- |---------:|----------:|----------:|-----:|
|   Your | 4.463 us | 0.0882 us | 0.1936 us |    2 |
|   Mine | 2.597 us | 0.0235 us | 0.0220 us |    1 |

n=1000

| Method |       Mean |       Error |      StdDev | Rank |
|------- |-----------:|------------:|------------:|-----:|
|   Your | 6,095.8 us | 119.4976 us | 122.7152 us |    2 |
|   Mine |   148.1 us |   0.6086 us |   0.5692 us |    1 |

Upvotes: 5

Theodor Zoulias
Theodor Zoulias

Reputation: 44026

Keeping the Random outside of the method as a static variable ensures that you'll always get a different list of numbers, even if you call the method many times in quick succession.

private static Random StaticRandom = new Random();

public static List<int> GetUniqueRandomNumbers_From_1_to_26()
{
    return Enumerable.Range(1, 26).OrderBy(_ => StaticRandom.Next()).ToList();
}

Usage example:

Console.WriteLine(String.Join(", ", GetUniqueRandomNumbers_From_1_to_26()));

Output:

26, 19, 22, 24, 16, 20, 5, 1, 8, 6, 10, 14, 13, 18, 15, 12, 25, 2, 4, 9, 21, 7, 23, 11, 3, 17

Upvotes: 0

koryakinp
koryakinp

Reputation: 4135

As an alternative you can use MathNet.Numerics library:

PM> Install-Package MathNet.Numerics

public static List<int> GetRandom()
{
    var arr = Combinatorics.GeneratePermutation(25);
    return new List<int>(arr);
}

You may need add 1, as it generates zero-based array.

Here is relevant documentation:

Generate a random permutation, without repetition, by generating the index numbers 0 to N-1 and shuffle them randomly. Implemented using Fisher-Yates Shuffling.

Upvotes: 0

Paulo Campez
Paulo Campez

Reputation: 702

thats because you are trying to get numbers between 1-25, so your code will never leave loop. you should call random like this

int randomNumber = rnd.Next(1, 27);

Upvotes: 5

Related Questions