shuffle (rearrange randomly) a List<string>
82,965
Solution 1
List<Foo> source = ...
var rnd = new Random();
var result = source.OrderBy(item => rnd.Next());
Obviously if you want real randomness instead of pseudo-random number generator you could use RNGCryptoServiceProvider instead of Random.
Solution 2
This is an extension method that will shuffle a List<T>
:
public static void Shuffle<T>(this IList<T> list) {
int n = list.Count;
Random rnd = new Random();
while (n > 1) {
int k = (rnd.Next(0, n) % n);
n--;
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
Comments
-
brux about 4 years
I need to rearrange my List array, it has a non-determinable number of elements in it.
Can somebody give me example of how i do this, thanks
-
chillitom about 13 yearsNo.. this is a bad idea, read this: blogs.msdn.com/b/ericlippert/archive/2011/01/31/…
-
Sanjeevakumar Hiremath about 13 yearsIs there a real randmoness? I thought it is impossible.
-
Darin Dimitrov about 13 years@Sanjeevakumar Hiremath, no there is no real randomness indeed. But with RNGCryptoServiceProvider at least the randomness should be sufficient :-)
-
jp2code about 13 years+1 I've not tested this in my code (i.e. not sure if it works), but I like it so far! Does every element get shuffled, or is that not necessary?
-
kprobst about 13 yearsThe whole list is shuffled, yes. Note that for larger lists you might want to integrate a more random random generator (Darin's answer below) into the solution. I use it for smaller sets (say ~300 tops) and it works well enough.
-
Kevin about 13 yearsYou can just say
int k = rnd.Next(0, n)
. The%
is unnecessary since the dividend is always less thann
. -
Jon Hanna about 13 yearsLooks like a sound Fisher-Yates implementation, which is what I was going to offer.
-
Jon Hanna about 13 years@chillitom, no this doesn't have the problem in that article. In Eric's article, the randomness is poorly seeded, and also the comparison is breaking the total ordering requirement of comparison methods. In Darin's example here, each item is assigned a random number once, and then ordered according to it. I think kprobst's solution is still better (well-known efficient shuffling algorithm), but Darin's is correct too.
-
o0'. over 10 yearsBad idea, see comments here.
-
Piotr Kula over 10 yearsDoesnt seem to work. Always get a list in the same order? :(
-
Veverke about 9 yearssame as @ppumkin here.
-
ErikE over 8 yearsThere is a problem with this implementation! Initializing a new
Random
on each call will yield predictable shuffling results. Instead, placeprivate static readonly Random rnd = new Random();
into the static class this method sits in. Finally, it would have been nice if you had given your source for this answer credit, because then the flaw in your own post might have been discovered sooner before people went off and used it without any hint it needed fixing. -
Joshua Grosso Reinstate CMs almost 8 years@ppumpkin @Veverke This doesn't work as-is, because
rnd
is set tonew Random()
each time (i.e. with the same seed). Basically, setrnd
at the beginning of your program and then never assign to it again (make itstatic
or something). Then, the only line you actually need at shuffle-time is the first and the third. -
Veverke almost 8 years@ BalinKingOfMoria: thanks, but I must have tried it like you say, since I am used to Random and know that I need to give it a seed and use the same instance. I do not remember what I tried then, ... sounds strange I tried it as it is. Thanks, anyway.
-
TaW about 7 yearsI am used to Random and know that I need to give it a seed yes, give it a seed to create always the same sequence. don't give it a seed to create uniques sequences.
-
nishantvodoo almost 7 years
-
tolache over 4 yearsWhat is
item
in this example? Please forgive noobness.