- Home /
How can i shuffle a list
Using
using System.Collections.Generic;
I made a list
private List<string> alpha = new List<string>{"A", "B", "C", "D"};
I need a new shuffled list
eg :- {"C", "B", "D", "A"};
Using for loop i will show values in list.
How can i shuffle a list?
Answer by sona.viswam · Jul 05, 2013 at 06:32 AM
for (int i = 0; i < alpha.Count; i++) {
string temp = alpha[i];
int randomIndex = Random.Range(i, alpha.Count);
alpha[i] = alpha[randomIndex];
alpha[randomIndex] = temp;
}
This is the classic example of what not to do!! This will produce highly biased output. See here for more information.
Well there is no difference, now that you've fixed the code ;)
For those curious, the code used to say
int randomIndex = Random.Range(0, alpha.Count);
Which is incorrect for the reason listed above.
@JVLVince The original is already correct since Random.Range with int is exclusive. $$anonymous$$eaning it will be randomed between i and alpha.Count -1.
@JVLVince The original is already correct since Random.Range with int is exclusive. $$anonymous$$eaning it will be randomed between i and alpha.Count -1.
Answer by mister kik · Jul 29, 2014 at 10:33 AM
Try that : listRand.Sort((a, b)=> 1 - 2 * Random.Range(0, 1));
It does not work. It shuffle but the result order is always the same. So, if the list is (A,B,C). The result of applying this function will always be (C,B,A).
It's better if you do it like that:
listRand.Sort((a, b)=> 1 - 2 * Random.Range(0, listRand.Count));
It works like this.
No, this makes no sense. The Sort method expects a delegate / function that returns either a positive, a negative or 0. When the value is 0 the two elements are considered equal. The other two cases sort them either the one way or the other. When you use "listRand.Count" as upper bounds it means only a random value of 0 could yield a positive number. Any other value would result in a negative number. So when you shuffle an array with many elements, most of the time you would return a negative value. The exact outcome now depends highly on the actual sorting algorithm. However I don't think the actual distribution of this approach is great or can actually be reasoned about. The basic "idea" behind this approach would be to randomly decide whether the two elements should be swapped or not. For this you would need to use
listRand.Sort((a, b)=> 1 - 2 * Random.Range(0, 2));
Passing 1 as second argument is pointless since in the case of the op (when using Random.Range(0, 1)
) Random.Range would always return 0, all the time. The max bounds of the integer version of Random.Range is exclusive.
As I said the whole approach is pretty pointless. Sort also usually uses quick sort. Quick sort has an average and worst case runtime of O(n log n). In comparison when doing a normal fisher-yates shuffle the runtime is linear O(n).
So I highly recommend to stay away from this approach.
Thanks for advice. However, I did it and it seems efficient in that way I used before. It shuffles whole List -probably- in efficient way. But I'm not sure if we could use more efficient way. Do you have advice about it?
Some other guys used other ways like sorting them all with loops. So, I don't know how to measure efficiency... That would be nice if we can find a way better... Thanks again.
Answer by pKallv · Apr 15, 2015 at 07:58 PM
//================================================================//
//===================Fisher_Yates_CardDeck_Shuffle====================//
//================================================================//
/// With the Fisher-Yates shuffle, first implemented on computers by Durstenfeld in 1964,
/// we randomly sort elements. This is an accurate, effective shuffling method for all array types.
public static List<GameObject> Fisher_Yates_CardDeck_Shuffle (List<GameObject>aList) {
System.Random _random = new System.Random ();
GameObject myGO;
int n = aList.Count;
for (int i = 0; i < n; i++)
{
// NextDouble returns a random number between 0 and 1.
// ... It is equivalent to Math.random() in Java.
int r = i + (int)(_random.NextDouble() * (n - i));
myGO = aList[r];
aList[r] = aList[i];
aList[i] = myGO;
}
return aList;
}
Please be aware that this algorithm can produce index out of bounds exception, when "_random.NextDouble()" returns 1.0f.
use this ins$$anonymous$$d:
int r = i + (int)(_random.NextDouble() * (n - i - 1));
@$$anonymous$$nightPista: Random.NextDouble() never returns 1.0. See https://msdn.microsoft.com/en-us/library/system.random.nextdouble(v=vs.110).aspx
this worked in my game & does a good job of shuffling my deck. Thanks very much, i used the regular .next but it did not work well.
Answer by Em3rgency · Jul 04, 2013 at 12:55 PM
A quick google search yielded this: http://stackoverflow.com/questions/273313/randomize-a-listt-in-c-sharp
I would suggest the Fisher-Yates shuffle as well. In fact, I would have if this answer wasn't here. :)
i cant use new Random() in unity 3d. i still confused how to implement Fisher-Yates in unity, Being a fresher.
you have to use:
System.Random rnd = new System.Random();
because unity has one & so does C# & the compiler gets confused as to which one to use.
Unity has its own random function. http://docs.unity3d.com/Documentation/ScriptReference/Random.Range.html
//here is an example... int a, v; List audClipIdxList; public AudioClip[] audClipArry;//supply in inspector void Awake(){ audClipIdxList=new List(audClipArry.Length); for(;a
Dude, you wanted a random shuffle algorithm. We gave you several. If you wan't something specific, modify it to your needs. Don't expect people to give you something absolutely ready so you could just copy-paste it in. We're here to help, not do work for you.
Answer by NatCou · Feb 09, 2019 at 05:21 PM
after a little search this is how I got mine to work...
Maybe it helps somebody else :)
void Shuffle(List<GameObject> a)
{
// Loop array
for (int i = a.Count - 1; i > 0; i--)
{
// Randomize a number between 0 and i (so that the range decreases each time)
int rnd = UnityEngine.Random.Range(0, i);
// Save the value of the current i, otherwise it'll overwrite when we swap the values
GameObject temp = a[i];
// Swap the new and old values
a[i] = a[rnd];
a[rnd] = temp;
}
// Print
for (int i = 0; i < a.Count; i++)
{
Debug.Log(a[i]);
}
}
Your answer
Follow this Question
Related Questions
List Bug when using debugger 1 Answer
OnTriggerEnter2D(collidertype coll) C# 1 Answer
panel hide and show in NGUI 1 Answer
Multiple Cars not working 1 Answer