ここでは、配列やListをキーや値の基になるようにして、Dictionary(System.Collections.Generic名前空間)を作成する方法を紹介します。なおDictionaryクラスは、.NET Framework 2.0以降で使用できます。
ここで紹介しているサンプルでは配列を基にしてDictionaryを作成していますが、配列の代わりにコレクションを使用しても同じようにできます。
まずはFor文を使った、何の工夫もない、基本的な方法から紹介します。この方法ならば、Dictionaryだけでなく、Hashtableでもできます。
以下の例では、2つの配列の片方がキー、もう片方が値になるようなDictionaryを作成しています。
'Imports System.Collections.Generic 'Dictionaryのキーにする配列 Dim keys As Integer() = New Integer() {1, 2, 3} 'Dictionaryの値にする配列 Dim vals As String() = New String() {"いち", "に", "さん"} 'Dictionaryオブジェクトを作成する Dim dic As New Dictionary(Of Integer, String)(keys.Length) 'For文で繰り返す Dim i As Integer For i = 0 To keys.Length - 1 'キーがkeys(i)である要素の値をvals(i)にする dic(keys(i)) = vals(i) '次のようにすると、キーが既に存在している時は例外がスローされる 'dic.Add(keys(i), vals(i)) Next
//using System.Collections.Generic; //Dictionaryのキーにする配列 int[] keys = new int[] { 1, 2, 3 }; //Dictionaryの値にする配列 string[] vals = new string[] { "いち", "に", "さん" }; //Dictionaryオブジェクトを作成する Dictionary<int, string> dic = new Dictionary<int, string>(keys.Length); //For文で繰り返す for (int i = 0; i < keys.Length; i++) { //キーがkeys[i]である要素の値をvals[i]にする dic[keys[i]] = vals[i]; //次のようにすると、キーが既に存在している時は例外がスローされる //dic.Add(keys[i], vals[i]); }
.NET Framework 3.5以降でLINQが使えるのであれば、Enumerable.ToDictionaryメソッドを使って配列やコレクションをDictionaryに変換できます。
以下の例では、配列の要素がキー、要素のToStringメソッドの結果が値になるようなDictionaryを作成しています。
'Imports System.Linq 'Imports System.Collections.Generic '基になる配列(コレクションでも可) Dim nums As Integer() = New Integer() {1, 2, 3} '配列の要素がキー、要素をToStringしたものが値になるようにして、 ' Dictionaryオブジェクトを作成する Dim dic As Dictionary(Of Integer, String) = _ nums.ToDictionary(Function(n) n, Function(n) n.ToString())
//using System.Linq; //using System.Collections.Generic; //基になる配列(コレクションでも可) int[] nums = new int[] { 1, 2, 3 }; //配列の要素がキー、要素をToStringしたものが値になるようにして、 // Dictionaryオブジェクトを作成する Dictionary<int, string> dic = nums.ToDictionary(n => n, n => n.ToString());
一番初めのFor文を使った例のように、LINQを使って2つの配列からDictionaryを作成する方法を考えてみます。
まずは、Enumerable.Zipメソッドを使ってみましょう。Zipで2つの配列から1つのシーケンスを作成して、それを使ってToDictionaryメソッドでDictionaryを作成します。
'Imports System.Linq 'Imports System.Collections.Generic 'Dictionaryのキーにする配列(コレクションでも可) Dim keys As Integer() = New Integer() {1, 2, 3} 'Dictionaryの値にする配列(コレクションでも可) Dim vals As String() = New String() {"いち", "に", "さん"} 'Zipを使って2つの配列の要素をプロパティに持つ匿名型のシーケンスを作り、 ' ToDictionaryでDictionaryを作る Dim dic As Dictionary(Of Integer, String) = _ keys.Zip(vals, Function(k, v) New With {k, v}) _ .ToDictionary(Function(a) a.k, Function(a) a.v)
//using System.Linq; //using System.Collections.Generic; //Dictionaryのキーにする配列(コレクションでも可) int[] keys = new int[] { 1, 2, 3 }; //Dictionaryの値にする配列(コレクションでも可) string[] vals = new string[] { "いち", "に", "さん" }; //Zipを使って2つの配列の要素をプロパティに持つ匿名型のシーケンスを作り、 // ToDictionaryでDictionaryを作る Dictionary<int, string> dic = keys.Zip(vals, (k, v) => new { k, v }) .ToDictionary(a => a.k, a => a.v);
Enumerable.Selectメソッドを使うと、要素のインデックスが分かります。これを使うと、次のようになります。
'Imports System.Linq 'Imports System.Collections.Generic 'Dictionaryのキーにする配列(コレクションでも可) Dim keys As Integer() = New Integer() {1, 2, 3} 'Dictionaryの値にする配列(コレクションでも可) Dim vals As String() = New String() {"いち", "に", "さん"} 'Selectを使って2つの配列の要素をプロパティに持つ匿名型のシーケンスを作り、 ' ToDictionaryでDictionaryを作る Dim dic As Dictionary(Of Integer, String) = _ keys.[Select](Function(k, i) New With {k, Key .v = vals(i)}) _ .ToDictionary(Function(a) a.k, Function(a) a.v)
//using System.Linq; //using System.Collections.Generic; //Dictionaryのキーにする配列(コレクションでも可) int[] keys = new int[] { 1, 2, 3 }; //Dictionaryの値にする配列(コレクションでも可) string[] vals = new string[] { "いち", "に", "さん" }; //Selectを使って2つの配列の要素をプロパティに持つ匿名型のシーケンスを作り、 // ToDictionaryでDictionaryを作る Dictionary<int, string> dic = keys.Select((k, i) => new { k, v = vals[i] }) .ToDictionary(a => a.k, a => a.v);
Enumerable.Rangeメソッドを使えば指定した範囲の整数のシーケンスを作成できますので、これを使って次のようにもできます。
'Imports System.Linq 'Imports System.Collections.Generic 'Dictionaryのキーにする配列(コレクションでも可) Dim keys As Integer() = New Integer() {1, 2, 3} 'Dictionaryの値にする配列(コレクションでも可) Dim vals As String() = New String() {"いち", "に", "さん"} 'Rangeで0から要素数までのシーケンスを作成し、ToDictionaryでDictionaryを作る Dim dic As Dictionary(Of Integer, String) = _ Enumerable.Range(0, keys.Length) _ .ToDictionary(Function(i) keys(i), Function(i) vals(i))
//using System.Linq; //using System.Collections.Generic; //Dictionaryのキーにする配列(コレクションでも可) int[] keys = new int[] { 1, 2, 3 }; //Dictionaryの値にする配列(コレクションでも可) string[] vals = new string[] { "いち", "に", "さん" }; //Rangeで0から要素数までのシーケンスを作成し、ToDictionaryでDictionaryを作る Dictionary<int, string> dic = Enumerable.Range(0, keys.Length) .ToDictionary(i => keys[i], i => vals[i]);