有没有一种简单的方法可以在 VB.NET 中随机化列表?
我有一个 System.IO.FileInfo
类型的列表,我想随机化这个列表.我想我记得不久前看到过类似 list.randomize()
的东西,但我找不到在哪里看到过.
I have a list of type System.IO.FileInfo
, and I would like to randomize the list. I thought I remember seeing something like list.randomize()
a little while back but I cannot find where I may have seen that.
我第一次尝试使用这个功能:
My first foray into this yielded me with this function:
Private Shared Sub GetRandom(ByVal oMax As Integer, ByRef currentVals As List(Of Integer))
Dim oRand As New Random(Now.Millisecond)
Dim oTemp As Integer = -1
Do Until currentVals.Count = IMG_COUNT
oTemp = oRand.Next(1, oMax)
If Not currentVals.Contains(oTemp) Then currentVals.Add(oTemp)
Loop
End Sub
我向它发送我希望它迭代到的最大 val,以及对我想要随机化内容的列表的引用.变量 IMG_COUNT
在脚本中设置得更远,指定如何我想显示许多随机图像.
I send it the max val I want it to iterate up to, and a reference to the list I want the randomized content in. The variable IMG_COUNT
is set farther up in the script, designating how many random images I want displayed.
谢谢大家,我很感激:D
Thanks guys, I appreciate it :D
构建比较器:
Public Class Randomizer(Of T)
Implements IComparer(Of T)
''// Ensures different instances are sorted in different orders
Private Shared Salter As New Random() ''// only as random as your seed
Private Salt As Integer
Public Sub New()
Salt = Salter.Next(Integer.MinValue, Integer.MaxValue)
End Sub
Private Shared sha As New SHA1CryptoServiceProvider()
Private Function HashNSalt(ByVal x As Integer) As Integer
Dim b() As Byte = sha.ComputeHash(BitConverter.GetBytes(x))
Dim r As Integer = 0
For i As Integer = 0 To b.Length - 1 Step 4
r = r Xor BitConverter.ToInt32(b, i)
Next
Return r Xor Salt
End Function
Public Function Compare(x As T, y As T) As Integer _
Implements IComparer(Of T).Compare
Return HashNSalt(x.GetHashCode()).CompareTo(HashNSalt(y.GetHashCode()))
End Function
End Class
像这样使用它,假设你的意思是一个通用的List(Of FileInfo)
:
Use it like this, assuming you mean a generic List(Of FileInfo)
:
list.Sort(New Randomizer(Of IO.FileInfo)())
您也可以使用闭包使随机值粘滞",然后在其上使用 linq 的 .OrderBy()(这次是 C#,因为 VB lambda 语法很难看):
You can also use a closure to make the random value 'sticky' and then just use linq's .OrderBy() on that (C# this time, because the VB lambda syntax is ugly):
list = list.OrderBy(a => Guid.NewGuid()).ToList();
在这里解释,以及为什么它甚至可能不如真正的洗牌快:
http://www.codinghorror.com/blog/archives/001008.html?r=31644
Explained here, along with why it might not even be as fast as real shuffle:
http://www.codinghorror.com/blog/archives/001008.html?r=31644