【发布时间】:2013-12-07 16:54:07
【问题描述】:
vb.net 的 java.util.Collections.shuffle() 方法的等价物是什么?我在 MSDN 上没有找到类似的东西。非常感谢您的帮助。
【问题讨论】:
-
我认为没有原生的,但你可以查看这篇文章。他们在那里提出了一些解决方案http://stackoverflow.com/q/554587/2619091
vb.net 的 java.util.Collections.shuffle() 方法的等价物是什么?我在 MSDN 上没有找到类似的东西。非常感谢您的帮助。
【问题讨论】:
(据我所知)没有内置的 .NET 函数,但使用 Linq 很容易编写一个通用的等效函数:
Function Shuffle(Of T)(collection As IEnumerable(Of T)) As List(Of T)
Dim r As Random = New Random()
Shuffle = collection.OrderBy(Function(a) r.Next()).ToList()
End Function
调用此函数会为输入列表中的每个元素分配一个随机值,然后按该随机数排序,返回一个新的(打乱后的)列表。
如果集合是一个数组或从IList 派生,一种更高效的方法可能是使用Fisher-Yates algorithm 就地打乱列表:
Sub Shuffle(Of T)(list As IList(Of T))
Dim r As Random = New Random()
For i = 0 To list.Count - 1
Dim index As Integer = r.Next(i, list.Count)
If i <> index Then
' swap list(i) and list(index)
Dim temp As T = list(i)
list(i) = list(index)
list(index) = temp
End If
Next
End Sub
【讨论】:
Calling this function assigns a random value to each element in an input list, and then sorts by that random number 这不是真的。它在每次比较时为元素分配随机数。 shuffle 算法需要与集合中的许多元素进行多次比较,这每次都会使用不同的随机值,这会使算法陷入意想不到的境地。事实上,甚至不能保证排序会完成,这可能会产生运行时异常。 Fisher-Yates不关注性能。这是关于正确性,并让它真正随机。
OrderBy 的情况下,它按照@drf 的描述工作,即每个项目生成一个值,并根据这些值对列表进行排序。当您调用 Sort 方法时,该方法采用直接执行两个项目比较的对象或委托,您描述的内容成为问题。例如。当传递 IComparer(Of T) 对象或 Comparison(Of T) 委托时。 OrderBy 这样工作得很好。
OrderBy 规范似乎没有专门解决非确定性排序函数的情况;参考源似乎表明排序是稳定的,因为内部类EnumerableSorter 碰巧每个项目调用一次键选择器。如果只是为了澄清意图并避免依赖实现细节,使用(在 C# 中)var r = new Random(); return l.Select(i=>new {Value=i, SortKey = r.Next()}).OrderBy(i=>i.SortKey).Select(i=>i.Value).ToList(); 的内容可能会更安全。