按随机数顺序排序列表

dot*_*oob 0 c# asp.net random

我有一个列表,我想每次排序成随机顺序.

我遇到过几种方法:

  1. list = list.OrderBy(x => Guid.NewGuid()).ToList();
    
    Run Code Online (Sandbox Code Playgroud)
  2. var rnd = new Random();
    myList = myList.OrderBy(x => rnd.Next()).ToList();
    
    Run Code Online (Sandbox Code Playgroud)
  3. static Random random = new Random();
    
    public static IEnumerable<T> RandomPermutation<T>(IEnumerable<T> sequence)
    {
        T[] retArray = sequence.ToArray();
    
        for (int i = 0; i < retArray.Length - 1; i += 1)
        {
            int swapIndex = random.Next(i + 1, retArray.Length);
            T temp = retArray[i];
            retArray[i] = retArray[swapIndex];
            retArray[swapIndex] = temp;
        }
    
        return retArray;
    }
    
    Run Code Online (Sandbox Code Playgroud)

显然,1到3之间的代码量有很大差异,但是有什么好处吗?

Ser*_*rvy 6

第一个是坏事. GUID是唯一的,但它们不一定是随机的. 虽然一些GUID实现可能依赖于随机性,但其他实现不会.这样的结果是在一台机器上运行的完全相同的程序将起作用,而在另一台机器上运行则不会 这真的很糟糕,因为这意味着你将测试你的程序,它会很好,你会发货,事情会破裂.

第三个是非常标准的改组算法.这通常是解决这个问题时我会选择的.

第二个选项可行,但效率明显低于第三个选项.排序具有比你在那里显示的第三个算法更高的渐近复杂度(O(n*log(n))而不是O(n)).

如果你每次想要使用它时都必须编写代码,那么方法中的值可能是2行而不是12行,但是当你只需要编写一次并且只需引用那个通用的shuffle方法时需要对一个序列进行混洗,你可以使用语义上正确且更有效的代码来证明这一点.(毕竟它不是那么长或复杂.)