modest violet

読者です 読者をやめる 読者になる 読者になる

modest violet

開発者としてのあれこれや、日々の雑記など

your future hasn't written yet. no one's has.
by Emmett Lathrop "Doc" Brown

VBでList Of のクラスを簡単にDictionaryに変換する方法

いやー、LINQは本当に便利。使えば使うほど魅力的です。

List(Of T)のリストを簡単にDictionaryに変換する方法です。

例として、IDと名称を保持する為のクラスです。

Class Hoge()

    Public Id As Integer
    Public Value As String

End Class

これに値を入れて、List(Of Hoge)として保持します。普通はこれで何も問題なし。
でもたまにIdで検索をしてValueを取得したいケースとかがあります。

Dictionaryを使わず昔ながらのループで探す方法

Dictionaryを知らなかった頃はこんな感じで書いていました。

Function GetValueById(id as integer) As String

     '' hoges に値が入っている前提
    For Each item in hoges
 
        if item.Id = id Then

            Return item.Value

        End if
    Next

End Function

昔ながらの方法ですね。件数が多い場合は、クイックソートとかバブルソートとか駆使しますが、基本は一致するまでForを回す力技です。

Dictionaryを使った検索

Dictionaryのキーに指定するとインデックスが効くので処理が早くなります。数万行とかのデータになれば効果テキメンです。
hogesをDictionary(Of Integer, Hoge) でデータを用意した場合の検索はこんな感じです。

Function GetValueById(id as integer) As String

     '' hoges に値が入っている前提
    If hoges.ContainsKey(id) Then

        Return hoges(id)

    End if
    
End Function

これだけです。ForNextが要らなくなりました。最初からDictionaryで値を保持しておけばインデックス検索の場合は楽ですね。

List (Of T) を Dictionary に変換する(LINQ前夜)

LINQを知るまではこんな感じでForEachで再作成していました。もっといい手があったかもしれませんが、実際にはこう作成しておりました。

Function ToHogeDictionary() As Dictionary(Of Integer, Hoge)

    Dim dicHoges As New Dictionary(Of Integer, Hoge)

    For Each hoge In hoges

    ' DictionaryのキーにId、値に hoge を指定
        dicHoges.Add(hoge.Id, hoge)

    Next

    Return dicHoges
    
End Function

簡単にList (Of T) を Dictionary に変換する

さて、ようやく目的の処理です。For文でグリグリっと作成していたDictionaryをどうやって変換するのか。

    hoges.ToDictionary(Function(x) x.Id)

たったこれだけ!!!

キーを指定するだけで、Valueの方は指定しなくてもOKなんですね。目からウロコでした。
LINQは本当に便利なんですけど、知らない方は結構躊躇するようです。(自分の周りだけでしょうか・・・)

複数行必要だった処理が1行で済んでしまうのは、結構やみつきになりますよ。