ソートしたりして 順番を調整する事は多くても、 敢えて、 ぐちゃぐちゃ にする 機会 は少ない筈です。
しかし、WPF で ListBox を使い、 一覧形式で 画像を表示した場合など、 毎回、同じ 顔ぶれ が並ぶのに、辟易 したりします。
そこで、 項目の ランダム な並び替え を。
今回も、Internet 検索で、有益な情報を 戴きました。
先ずは、その お礼 を述べさせて戴きます。 何時も、お世話になっております!。.
件の ご投稿 は こちら。 配列やコレクションをシャッフルする(ランダムに並び替える) - Dobon.Net プログラミング道
自分で考えて書いていると、 Bug の山。 まともに、動きもしません!。
乱数を使えば良いのは想像がついても、 何時まで経っても答えが返って来なかったり、 オーバーフローで中断させられたり ... 。
トホホ の時間が流れて行きます。
序でに、 アルゴリズムを考えられた 数学者さん って、偉いですね。 感謝です。
さて、本題。
項目のランダムな並び替えは 以下の コード を基本に、 Project に見合った形に OverLoads して使われると良いと思います。
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim sampleArray(15) As Integer
For n = 0 To sampleArray.Count - 1
sampleArray(n) = n
Next
MakeShuffle(sampleArray)
Me.TextBox1.Multiline = True '以下、結果を表示
Dim result As New System.Text.StringBuilder
For i As Integer = 0 To sampleArray.Count - 1
result = result.Append(i.ToString & " " & sampleArray(i) & vbCrLf)
Next
Me.TextBox1.Text = result.ToString
End Sub
Private Overloads Function MakeShuffle(ByVal itemsRandomArray() As Integer)
'Usage ; Before Using, Make Array With Items Count
' Dim sampleArray(Count - 1) As Integer
' sampleArray = MakeShuffle(sampleArray)
If itemsRandomArray.Count < 1 Then
Return Nothing
End If
Dim tc As Integer = Environment.TickCount 'Default Seed
Dim dm As Integer = Date.Now.Minute
Dim s As Integer = CInt(tc / dm) 'Set My Seed
'Fisher-Yates shuffle Algorithm
' Ref.; http://dobon.net/vb/dotnet/programing/arrayshuffle.html
'Dim rng As New System.Random() 'Default Seed
Dim rng As New System.Random(s) 'Set My Seed
Dim n As Integer = itemsRandomArray.Length
While n > 1
n -= 1
Dim k As Integer = rng.Next(n + 1)
Dim tmp As Integer = itemsRandomArray(k)
itemsRandomArray(k) = itemsRandomArray(n)
itemsRandomArray(n) = tmp
End While
Return itemsRandomArray
End Function
End Class
通常、項目は、 Collection や List で与えられるでしょうから、 それを当て嵌めます。
元の項目を確保して置き、暫定的に、別のものを作るなら、 コピーを操作する事になります。
その時は、 Index を、上記の手法で並び替えて、 それを基に、 コピーを作って行く方法もあります。
尚、SortedList の様に、Keys で元々並び替えているものを操作しても意味がありません。
この場合には、別の Generic な Collection 類(例えば List)に切り替えるか、
System.Collections.Specialized.OrderedDictionary の採用を検討するかになるでしょう。
0 件のコメント:
コメントを投稿