我有一个列表,我想每次排序成随机顺序.
我遇到过几种方法:
list = list.OrderBy(x => Guid.NewGuid()).ToList();
Run Code Online (Sandbox Code Playgroud)var rnd = new Random();
myList = myList.OrderBy(x => rnd.Next()).ToList();
Run Code Online (Sandbox Code Playgroud)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之间的代码量有很大差异,但是有什么好处吗?
第一个是坏事. GUID是唯一的,但它们不一定是随机的. 虽然一些GUID实现可能依赖于随机性,但其他实现不会.这样的结果是在一台机器上运行的完全相同的程序将起作用,而在另一台机器上运行则不会 这真的很糟糕,因为这意味着你将测试你的程序,它会很好,你会发货,事情会破裂.
第三个是非常标准的改组算法.这通常是解决这个问题时我会选择的.
第二个选项可行,但效率明显低于第三个选项.排序具有比你在那里显示的第三个算法更高的渐近复杂度(O(n*log(n))而不是O(n)).
如果你每次想要使用它时都必须编写代码,那么方法中的值可能是2行而不是12行,但是当你只需要编写一次并且只需引用那个通用的shuffle方法时需要对一个序列进行混洗,你可以使用语义上正确且更有效的代码来证明这一点.(毕竟它不是那么长或复杂.)