c# - Randomize a List<T> -


what best way randomize order of generic list in c#? i've got finite set of 75 numbers in list assign random order to, in order draw them lottery type application.

shuffle (i)list extension method based on fisher-yates shuffle:

private static random rng = new random();    public static void shuffle<t>(this ilist<t> list)   {       int n = list.count;       while (n > 1) {           n--;           int k = rng.next(n + 1);           t value = list[k];           list[k] = list[n];           list[n] = value;       }   } 

usage:

list<product> products = getproducts(); products.shuffle(); 

the code above uses criticised system.random method select swap candidates. it's fast not random should be. if need better quality of randomness in shuffles use random number generator in system.security.cryptography so:

using system.security.cryptography; ... public static void shuffle<t>(this ilist<t> list) {     rngcryptoserviceprovider provider = new rngcryptoserviceprovider();     int n = list.count;     while (n > 1)     {         byte[] box = new byte[1];         provider.getbytes(box);         while (!(box[0] < n * (byte.maxvalue / n)));         int k = (box[0] % n);         n--;         t value = list[k];         list[k] = list[n];         list[n] = value;     } } 

a simple comparison available at blog (wayback machine).

edit: since writing answer couple years back, many people have commented or written me, point out big silly flaw in comparison. of course right. there's nothing wrong system.random if it's used in way intended. in first example above, instantiate rng variable inside of shuffle method, asking trouble if method going called repeatedly. below fixed, full example based on useful comment received today @weston here on so.

program.cs:

using system; using system.collections.generic; using system.threading;  namespace simplelottery {   class program   {     private static void main(string[] args)     {       var numbers = new list<int>(enumerable.range(1, 75));       numbers.shuffle();       console.writeline("the winning numbers are: {0}", string.join(",  ", numbers.getrange(0, 5)));     }   }    public static class threadsaferandom   {       [threadstatic] private static random local;        public static random thisthreadsrandom       {           { return local ?? (local = new random(unchecked(environment.tickcount * 31 + thread.currentthread.managedthreadid))); }       }   }    static class myextensions   {     public static void shuffle<t>(this ilist<t> list)     {       int n = list.count;       while (n > 1)       {         n--;         int k = threadsaferandom.thisthreadsrandom.next(n + 1);         t value = list[k];         list[k] = list[n];         list[n] = value;       }     }   } } 

Comments

Popular posts from this blog

c++ - How do I get a multi line tooltip in MFC -

asp.net - In javascript how to find the height and width -

c# - DataTable to EnumerableRowCollection -