トップ回答者
配列をどう適用していいのかわかりません

質問
-
VB2010を利用しています。
次のようなコードをシンプルにしたいと思っております。
Dim check As String
Dim checklist001 As New List(Of String)
Dim checklist002 As New List(Of String)
Dim checklist003 As New List(Of String)check = "check002"
Select Case checkCase "check001"
checklist001.Add("check001")Case "check002"
checklist002.Add("check002")Case "check003"
checklist003.Add("check003")End Select
変数checkに代入された値に応じて、その値と同じ変数名を持つ、
LIST型のchecklist001~checklist003 になにがしかの処理を
行います。checkの値が上記のように3個であれば、select文を使う方法でも
かまいませんが、checkの値が1000個ですと、select文を記述する
ことは大変となってきます。checklist を配列、LIST、もしくは何らかの方法で定義し、
理想: checklist(check).add(check)
というようなスタイルで記述できれば短いコードですむと思うのですが、
その方法がわかりません。うまい方法をご存じでしたらご教授願います。
doratch
回答
-
こんな感じかなぁ。
Dim check As String = "check002" Dim checkList As New Dictionary(Of String, List(Of String)) 'リストにセット If Not checkList.ContainsKey(check) Then checkList.Add(check, New List(Of String)) End If checkList(check).Add(check) 'リストから抜き出し For Each pair As KeyValuePair(Of String, List(Of String)) In checkList Dim key As String = pair.Key Dim value As List(Of String) = pair.Value Next 'リストから指定キーを抜き出し If checkList.ContainsKey(check) Then Return checkList(check) Else Return New List(Of String) End If
すべての返信
-
こんな感じかなぁ。
Dim check As String = "check002" Dim checkList As New Dictionary(Of String, List(Of String)) 'リストにセット If Not checkList.ContainsKey(check) Then checkList.Add(check, New List(Of String)) End If checkList(check).Add(check) 'リストから抜き出し For Each pair As KeyValuePair(Of String, List(Of String)) In checkList Dim key As String = pair.Key Dim value As List(Of String) = pair.Value Next 'リストから指定キーを抜き出し If checkList.ContainsKey(check) Then Return checkList(check) Else Return New List(Of String) End If
-
解決されたみたいなのですが・・・
やろうとされていることは他の場所でも使うでのはないかと思いますので、
下記のように2つクラスを使ったほうがスマートかなと思います。Private Sub Exec() Dim CheckA As New Check(Of String) CheckA.Name = "Aのチェック" CheckA.TargetList.Add("aaa1") CheckA.TargetList.Add("aaa2") Dim CheckB As New Check(Of String) CheckB.Name = "Bのチェック" CheckB.TargetList.Add("bbb1") CheckB.TargetList.Add("bbb2") CheckB.TargetList.Add("bbb3") Dim MyCheck As New MyCheck(Of String) MyCheck.Checklist.Add(CheckA) MyCheck.Checklist.Add(CheckB) Dim SearchCheck As Check(Of String) SearchCheck = MyCheck.GetTargetList("Aのチェック") If SearchCheck IsNot Nothing Then SearchCheck.TargetList.Add("aaa3") End If '下記のようにもできますが、GetTargetListでNothingが帰ってくるとコケます MyCheck.GetTargetList("Aのチェック").TargetList.Add("aaa3") End Sub ''' <summary> ''' TargetListと名称のみもつクラス ''' </summary> Public Class Check(Of T) Private _Name As String = String.Empty Private _TargetList As New List(Of T) Public Property Name() Get Return _Name End Get Set(ByVal value) _Name = value End Set End Property Public Property TargetList() As List(Of T) Get Return _TargetList End Get Set(ByVal value As List(Of T)) _TargetList = value End Set End Property End Class ''' <summary> ''' Checkクラスのリストと検索メソッドを持つクラス ''' </summary> Public Class MyCheck(Of T) Private _CheckList As New List(Of Check(Of T)) Public Property Checklist() As List(Of Check(Of T)) Get Return _CheckList End Get Set(ByVal value As List(Of Check(Of T))) _CheckList = value End Set End Property Public Function GetTargetList(ByVal _name As String) As Check(Of T) Return _CheckList.Find(Function(p) p.Name = _name) End Function End Class
ジェネリッククラスとFindなどのメソッドはとても便利なのでちょっと時間を割いて習得されてはどうでしょうか。 -
このケースでスマートさを求めるのであれば、クラス2つはどうかと思います。
クラスは下記の1つで十分かと、
Public Class ListWithKey(Of T) Private _list As New Dictionary(Of String, List(Of T)) Public Function ListOf(ByVal key As String) As List(Of T) If Not _list.ContainsKey(key) Then _list.Add(key, New List(Of T)) End If Return _list(key) End Function End Class
これであれば、
Dim keyList As New ListWithKey(Of String) keyList.ListOf("Aのチェック").Add("aaa1") keyList.ListOf("Aのチェック").Add("aaa2") keyList.ListOf("Aのチェック").Add("aaa3") keyList.ListOf("Bのチェック").Add("bbb1") keyList.ListOf("Bのチェック").Add("bbb2") keyList.ListOf("Cのチェック").Add("ccc1") Dim list As List(Of String) = keyList.ListOf("Aのチェック")
みたいな形で未セットの時等も良い感じに使えるかと思います。※未セットのキーを取得しようとすると空のリストが取得される。
あとこれは余談ですが、
「MyCheck.GetTargetList("Aのチェック").TargetList.Add("aaa3")」
みたいに、GetTargetList メソッドの返り値のメンバに TargetList がいるってのはソースの誤読に繋がるので避けるべきだと思います。
Public Function GetTargetList(ByVal _name As String) As List(Of T) Return _CheckList.Find(Function(p) p.Name = _name).TargetList End Function
の方が良いと思います。