我有一个列表,我想每次都按随机顺序排序。
我遇到过几种方式:
list = list.OrderBy(x => Guid.NewGuid()).ToList();
var rnd = new Random();
myList = myList.OrderBy(x => rnd.Next()).ToList();
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;
}
显然,1到3之间的代码量存在很大差异,但有什么好处吗?
答案 0 :(得分:6)
第一个只是坏事。 GUIDs are unique, but they are not necessarily random.虽然某些GUID实现可能依赖于随机性,但其他人则不会。这样的结果是在一台机器上运行的完全相同的程序将起作用而在另一台机器上运行不会。这是非常糟糕,因为这意味着你将测试你的程序,它会很好,你会发货,事情会破裂。
第三种是非常标准的混洗算法。这通常是解决这个问题时我会采用的方法。
第二个选项可行,但效率明显低于第三个选项。排序具有比你在那里显示的第三个算法更高的渐近复杂度(O(n * log(n))而不是O(n))。
如果你每次想要使用它时都必须编写代码,那么方法中的值可能是2行而不是12行,但是当你只需要编写一次并简单地引用那个通用的shuffle方法时任何时候你需要改变一个序列,你可以证明使用语义上适当和更有效的代码。 (毕竟它不是 长或复杂。)