在c#中随机化泛型列表顺序的最佳方法是什么?我在一个列表中有一个有限的75个数字集,我想随机分配一个顺序,以便为彩票类型的应用程序绘制它们。


当前回答

我通常使用:

var list = new List<T> ();
fillList (list);
var randomizedList = new List<T> ();
var rnd = new Random ();
while (list.Count != 0)
{
    var index = rnd.Next (0, list.Count);
    randomizedList.Add (list [index]);
    list.RemoveAt (index);
}

其他回答

我在网上找到了一个有趣的解决办法。

礼貌:https://improveandrepeat.com/2018/08/a-simple-way-to-shuffle-your-lists-in-c/

var shuffled = myList。OrderBy(x => Guid.NewGuid()).ToList();

实现:

public static class ListExtensions
{
    public static void Shuffle<T>(this IList<T> list, Random random)
    {
        for (var i = list.Count - 1; i > 0; i--)
        {
            int indexToSwap = random.Next(i + 1);
            (list[indexToSwap], list[i]) = (list[i], list[indexToSwap]);
        }
    }
}

例子:

var random = new Random();
var array = new [] { 1, 2, 3 };
array.Shuffle(random);
foreach (var item in array) {
    Console.WriteLine(item);
}

.NET小提琴演示

I'm bit surprised by all the clunky versions of this simple algorithm here. Fisher-Yates (or Knuth shuffle) is bit tricky but very compact. Why is it tricky? Because your need to pay attention to whether your random number generator r(a,b) returns value where b is inclusive or exclusive. I've also edited Wikipedia description so people don't blindly follow pseudocode there and create hard to detect bugs. For .Net, Random.Next(a,b) returns number exclusive of b so without further ado, here's how it can be implemented in C#/.Net:

public static void Shuffle<T>(this IList<T> list, Random rnd)
{
    for(var i=list.Count; i > 0; i--)
        list.Swap(0, rnd.Next(0, i));
}

public static void Swap<T>(this IList<T> list, int i, int j)
{
    var temp = list[i];
    list[i] = list[j];
    list[j] = temp;
}

试试这段代码。

如果我们只需要以完全随机的顺序洗牌项目(只是在一个列表中混合项目),我更喜欢这个简单而有效的代码,按guid排序项目…

var shuffledcards = cards.OrderBy(a => Guid.NewGuid()).ToList();

正如人们在评论中指出的那样,guid不能保证是随机的,所以我们应该使用真正的随机数生成器:

private static Random rng = new Random();
...
var shuffledcards = cards.OrderBy(a => rng.Next()).ToList();

我通常使用:

var list = new List<T> ();
fillList (list);
var randomizedList = new List<T> ();
var rnd = new Random ();
while (list.Count != 0)
{
    var index = rnd.Next (0, list.Count);
    randomizedList.Add (list [index]);
    list.RemoveAt (index);
}