乱数を格納した配列を保持するクラスを作ってみた

乱数を格納した配列を保持するクラス

クラスへの移行

前回の

akashi-keirin.hatenablog.com

で、乱数を格納した配列を作るFunctionを作った。

実は、追記のところで、型指定でVariantを使うブサイクさ問題は解決ずみなんだが、乗りかかった船なのでやっておく。

まあ、クラスにしておけば、ひとたび生成した乱数保持配列をインスタンスごとに持たせておくことで複数使い回せる、というメリットがありそうだし(相変わらず使いどころは不明ですがw)。

ともかく、まずはクラスを作る。

リスト1 クラスモジュール

オブジェクト名は「RandomMaker」としている。

Option Explicit

'Fields'
Private randomIndex_() As Integer    '……(1)'

'Getter'
Public Property Get randomIndex(ByVal i As Integer) As Integer    '……(2)'
  randomIndex = randomIndex_(i)
End Property

'methods'
Public Sub setRandomArray(ByVal maxNum As Integer, _
                      ByVal allowDuplicate As Boolean)
  Dim flg() As Boolean
  ReDim flg(maxNum - 1)
  Dim i As Integer
  ReDim randomIndex_(maxNum - 1)
  Randomize
  Dim tmp As Integer
  For i = 0 To maxNum - 1
    Do
      tmp = Int(maxNum * Rnd + 1)
    '///乱数:Int((最大値 - 最小値 + 1) * Rnd + 最小値)'
    Loop Until flg(tmp - 1) = False
    randomIndex_(i) = tmp
    If Not allowDuplicate Then flg(tmp - 1) = True
  Next
End Sub

(1)の

Private randomIndex_() As Integer

は、配列保持用の変数。

(2)からの3行、

Public Property Get randomIndex(ByVal i As Integer) As Integer    '……(2)'
  randomIndex = randomIndex_(i)    '……(*)'
End Property

は、Getterメソッドに相当するもの。

akashi-keirin.hatenablog.com

のときにも書いたが、インスタンスに配列を持たせる形にしているけれど、プロパティとして配列を持っているわけではなく、プロパティを参照するときには、配列のインデックス番号を引数として渡して、内部の配列からその値を受け取ってプロパティの値を返す、という形になっているみたい。

だから、2行目の左辺には

randomIndex = randomIndex_(i)

のように、「(i)」が付かない、ということになる。

メソッド部分は何も変えていないので、説明は省略。

実行

次のコードでクラスを使用してみる。

せっかくなので、今度は

文字単位でランダムに並べ替えるマクロ

にしてみた。

スト2 標準モジュール
Public Sub randomSortByCharacter()
  Dim num As Integer
  Dim charArray() As String
  With Selection
    num = .Characters.Count
    ReDim charArray(num - 1)
    Dim i As Integer
    For i = 0 To num - 1
      charArray(i) = .Characters(i + 1)
    Next
  End With
  Dim randMaker As RandomMaker    '……(1)'
  Set randMaker = New RandomMaker
  Dim str As String
  With randMaker
    .setRandomArray num, False    '……(2)'
    For i = 0 To num - 1    '……(3)'
      str = str & charArray(.randomIndex(i) - 1)
    Next
  End With
  Selection.TypeText Text:=str
End Sub

操作の対象をSelectionオブジェクトのWordsコレクションからCharactersコレクションに変更しただけ。

あとは、(1)からの2行

Dim randMaker As RandomMaker
Set randMaker = New RandomMaker

でRandomMakerクラスのインスタンスを変数randMakerにぶち込んで、

(2)の

randMaker.setRandomArray num, False

で乱数を格納した配列を持たせ、

(3)の

For i = 0 To num - 1    '……(3)'
  str = str & charArray(.randomIndex(i) - 1)
Next

でRandomMakerクラスのrandomIndexプロパティを利用して文字を再構成して元の場所に上書きする。

実行結果

f:id:akashi_keirin:20171022080404j:plain

こんなふうに範囲指定して実行すると、

f:id:akashi_keirin:20171022080252j:plain

こんな感じ。

f:id:akashi_keirin:20171022080423j:plain

こんなふうに範囲指定して実行すると、

f:id:akashi_keirin:20171022080442j:plain

こんな感じになる。

おわりに

使い道はこれから考える。

@akashi_keirin on Twitter