[c#] Generating random, unique values C#

I've searched for a while and been struggling to find this, I'm trying to generate several random, unique numbers is C#. I'm using System.Random, and I'm using a DateTime.Now.Ticks seed:

public Random a = new Random(DateTime.Now.Ticks.GetHashCode());
private void NewNumber()
{
    MyNumber = a.Next(0, 10);
}

I'm calling NewNumber() regularly, but the problem is I often get repeated numbers. Some people suggested because I was declaring the random every time I did it, it would not produce a random number, so I put the declaration outside my function. Any suggestions or better ways than using System.Random ? Thank you

This question is related to c# .net random unique

The answer is


It's may be a little bit late, but here is more suitable code, for example when you need to use loops:

            List<int> genered = new List<int>();

            Random rnd = new Random();

            for(int x = 0; x < files.Length; x++)
            {
                int value = rnd.Next(0, files.Length - 1);
                while (genered.Contains(value))
                {
                    value = rnd.Next(0, files.Length - 1);
                }
                genered.Add(value);

                returnFiles[x] = files[value];
            }

This is a unity only answer:

Check this ready-to-use method: Give in a range & count of number you want to get.

public static int[] getUniqueRandomArray(int min, int max, int count) {
    int[] result = new int[count];
    List<int> numbersInOrder = new List<int>();
    for (var x = min; x < max; x++) {
        numbersInOrder.Add(x);
    }
    for (var x = 0; x < count; x++) {
        var randomIndex = UnityEngine.Random.Range(0, numbersInOrder.Count);
        result[x] = numbersInOrder[randomIndex];
        numbersInOrder.RemoveAt(randomIndex);
    }

    return result;
}

You can use basic Random Functions of C#

Random ran = new Random();
int randomno = ran.Next(0,100);

you can now use the value in the randomno in anything you want but keep in mind that this will generate a random number between 0 and 100 Only and you can extend that to any figure.


Try this:

private void NewNumber()
  {
     Random a = new Random(Guid.newGuid().GetHashCode());
     MyNumber = a.Next(0, 10);
  }

Some Explnations:

Guid : base on here : Represents a globally unique identifier (GUID)

Guid.newGuid() produces a unique identifier like "936DA01F-9ABD-4d9d-80C7-02AF85C822A8"

and it will be unique in all over the universe base on here

Hash code here produce a unique integer from our unique identifier

so Guid.newGuid().GetHashCode() gives us a unique number and the random class will produce real random numbers throw this

Sample: https://rextester.com/ODOXS63244

generated ten random numbers with this approach with result of:

-1541116401
7
-1936409663
3
-804754459
8
1403945863
3
1287118327
1
2112146189
1
1461188435
9
-752742620
4
-175247185
4
1666734552
7

we got two 1s next to each other, but the hash codes do not same.


unique random number from 0 to 9

      int sum = 0;
        int[] hue = new int[10];
        for (int i = 0; i < 10; i++)
        {

            int m;
            do
            {
                m = rand.Next(0, 10);
            } while (hue.Contains(m) && sum != 45);
            if (!hue.Contains(m))
            {
                hue[i] = m;
                sum = sum + m;
            }

        }

This console app will let you shuffle the alphabet five times with different orders.

using System;
using System.Linq;

namespace Shuffle
{
    class Program
    {
        static Random rnd = new Random();
        static void Main(string[] args)
        {
            var alphabet = new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
            Console.WriteLine("Alphabet : {0}", string.Join(",", alphabet)); 
            for (int i = 0; i < 5; i++)
            {
                var shuffledAlphabet = GetShuffledAlphabet(alphabet);
                Console.WriteLine("SHUFFLE {0}: {1}", i, string.Join(",", shuffledAlphabet));
            }
        }

        static string[] GetShuffledAlphabet(string[] arr)
        {
            int?[] uniqueNumbers = new int?[arr.Length];
            string[] shuffledAlphabet = new string[arr.Length];

            for (int i = 0; i < arr.Length; i++)
            {
                int uniqueNumber = GenerateUniqueNumber(uniqueNumberArrays);
                uniqueNumberArrays[i] = uniqueNumber;
                newArray[i] = arr[uniqueNumber];
            }

            return shuffledAlphabet;
        }

        static int GenerateUniqueNumber(int?[] uniqueNumbers)
        {
            int number = rnd.Next(uniqueNumbers.Length);

            if (!uniqueNumbers.Any(r => r == number))
            {
                return number;
            }

            return GenerateUniqueNumber(uniqueNumbers);
        }
    }
}

I'm posting a correct implementation of a shuffle algorithm, since the other one posted here doesn't produce a uniform shuffle.

As the other answer states, for small numbers of values to be randomized, you can simply fill an array with those values, shuffle the array, and then use however many of the values that you want.

The following is an implementation of the Fisher-Yates Shuffle (aka the Knuth Shuffle). (Read the "implementation errors" section of that link (search for "always selecting j from the entire range of valid array indices on every iteration") to see some discussion about what is wrong with the other implementation posted here.)

using System;
using System.Collections.Generic;

namespace ConsoleApplication2
{
    static class Program
    {
        static void Main(string[] args)
        {
            Shuffler shuffler = new Shuffler();
            List<int> list = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            shuffler.Shuffle(list);

            foreach (int value in list)
            {
                Console.WriteLine(value);
            }
        }
    }

    /// <summary>Used to shuffle collections.</summary>

    public class Shuffler
    {
        /// <summary>Creates the shuffler with a <see cref="MersenneTwister"/> as the random number generator.</summary>

        public Shuffler()
        {
            _rng = new Random();
        }

        /// <summary>Shuffles the specified array.</summary>
        /// <typeparam name="T">The type of the array elements.</typeparam>
        /// <param name="array">The array to shuffle.</param>

        public void Shuffle<T>(IList<T> array)
        {
            for (int n = array.Count; n > 1; )
            {
                int k = _rng.Next(n);
                --n;
                T temp = array[n];
                array[n] = array[k];
                array[k] = temp;
            }
        }

        private System.Random _rng;
    }
}

I noted that the accepted answer keeps adding int to the list and keeps checking them with if (!randomList.Contains(MyNumber)) and I think this doesn't scale well, especially if you keep asking for new numbers.

I would do the opposite.

  1. Generate the list at startup, linearly
  2. Get a random index from the list
  3. Remove the found int from the list

This would require a slightly bit more time at startup, but will scale much much better.

public class RandomIntGenerator
{
    public Random a = new Random();
    private List<int> _validNumbers;

    private RandomIntGenerator(int desiredAmount, int start = 0)
    {
        _validNumbers = new List<int>();
        for (int i = 0; i < desiredAmount; i++)
            _validNumbers.Add(i + start);
    }

    private int GetRandomInt()
    {
        if (_validNumbers.Count == 0)
        {
            //you could throw an exception here
            return -1;
        }
        else
        {
            var nextIndex = a.Next(0, _validNumbers.Count - 1);
            var number    = _validNumbers[nextIndex];
            _validNumbers.RemoveAt(nextIndex);
            return number;
        }
    }
}

You might try shuffling an array of possible ints if your range is only 0 through 9. This adds the benefit of avoiding any conflicts in the number generation.

var nums = Enumerable.Range(0, 10).ToArray();
var rnd = new Random();

// Shuffle the array
for (int i = 0;i < nums.Length;++i)
{
    int randomIndex = rnd.Next(nums.Length);
    int temp = nums[randomIndex];
    nums[randomIndex] = nums[i];
    nums[i] = temp;
}

// Now your array is randomized and you can simply print them in order
for (int i = 0;i < nums.Length;++i)
    Console.WriteLine(nums[i]);

You could also use a dataTable storing each random value, then simply perform the random method while != values in the dataColumn


hi here i posted one video ,and it explains how to generate unique random number

  public List<int> random_generator(){

  Random random = new Random();

   List<int> random_container = new List<int>;

     do{

       int random_number = random.next(10);

      if(!random_container.contains(random_number){

       random_container.add(random_number)
  }
}
   while(random_container.count!=10);


     return random_container; 
  }

here ,,, in random container you will get non repeated 10 numbers starts from 0 to 9(10 numbers) as random.. thank you........


Depending on what you are really after you can do something like this:

using System;
using System.Collections.Generic;
using System.Linq;

namespace SO14473321
{
    class Program
    {
        static void Main()
        {
            UniqueRandom u = new UniqueRandom(Enumerable.Range(1,10));
            for (int i = 0; i < 10; i++)
            {
                Console.Write("{0} ",u.Next());
            }
        }
    }

    class UniqueRandom
    {
        private readonly List<int> _currentList;
        private readonly Random _random = new Random();

        public UniqueRandom(IEnumerable<int> seed)
        {
            _currentList = new List<int>(seed);
        }

        public int Next()
        {
            if (_currentList.Count == 0)
            {
                throw new ApplicationException("No more numbers");
            }

            int i = _random.Next(_currentList.Count);
            int result = _currentList[i];
            _currentList.RemoveAt(i);
            return result;
        }
    }
}

randomNumber function return unqiue integer value between 0 to 100000

  bool check[] = new bool[100001];
  Random r = new Random();
  public int randomNumber() {
      int num = r.Next(0,100000);
       while(check[num] == true) {
             num = r.Next(0,100000);
     }
    check[num] = true;
   return num;
 }

And here my version of finding N random unique numbers using HashSet. Looks pretty simple, since HashSet can contain only different items. It's interesting - would it be faster then using List or Shuffler?

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    class RnDHash
    {
        static void Main()
        {
            HashSet<int> rndIndexes = new HashSet<int>();
            Random rng = new Random();
            int maxNumber;
            Console.Write("Please input Max number: ");
            maxNumber = int.Parse(Console.ReadLine());
            int iter = 0;
            while (rndIndexes.Count != maxNumber)
            {
                int index = rng.Next(maxNumber);
                rndIndexes.Add(index);
                iter++;
            }
            Console.WriteLine("Random numbers were found in {0} iterations: ", iter);
            foreach (int num in rndIndexes)
            {
                Console.WriteLine(num);
            }
            Console.ReadKey();
        }
    }
}

Same as @Habib's answer, but as a function:

List<int> randomList = new List<int>();
int UniqueRandomInt(int min, int max)
{
    var rand = new Random();
    int myNumber;
    do
    {
       myNumber = rand.Next(min, max);
    } while (randomList.Contains(myNumber));
    return myNumber;
}

If randomList is a class property, UniqueRandomInt will return unique integers in the context of the same instance of that class. If you want it to be unique globally, you will need to make randomList static.


NOTE, I dont recommend this :). Here's a "oneliner" as well:

//This code generates numbers between 1 - 100 and then takes 10 of them.
var result = Enumerable.Range(1,101).OrderBy(g => Guid.NewGuid()).Take(10).ToArray();

Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to .net

You must add a reference to assembly 'netstandard, Version=2.0.0.0 How to use Bootstrap 4 in ASP.NET Core No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization .net Core 2.0 - Package was restored using .NetFramework 4.6.1 instead of target framework .netCore 2.0. The package may not be fully compatible Update .NET web service to use TLS 1.2 EF Core add-migration Build Failed What is the difference between .NET Core and .NET Standard Class Library project types? Visual Studio 2017 - Could not load file or assembly 'System.Runtime, Version=4.1.0.0' or one of its dependencies Nuget connection attempt failed "Unable to load the service index for source" Token based authentication in Web API without any user interface

Examples related to random

How can I get a random number in Kotlin? scikit-learn random state in splitting dataset Random number between 0 and 1 in python In python, what is the difference between random.uniform() and random.random()? Generate random colors (RGB) Random state (Pseudo-random number) in Scikit learn How does one generate a random number in Apple's Swift language? How to generate a random string of a fixed length in Go? Generate 'n' unique random numbers within a range What does random.sample() method in python do?

Examples related to unique

Count unique values with pandas per groups Find the unique values in a column and then sort them How can I check if the array of objects have duplicate property values? Firebase: how to generate a unique numeric ID for key? pandas unique values multiple columns Select unique values with 'select' function in 'dplyr' library Generate 'n' unique random numbers within a range SQL - select distinct only on one column Can I use VARCHAR as the PRIMARY KEY? Count unique values in a column in Excel