ハッシュテーブル

Similar documents
Visual Basic 資料 電脳梁山泊烏賊塾 コレクション初期化子 コレクション初期化子 初めに.NET 版の Visual Basic では 其れ迄の Visual Basic 6.0 とは異なり 下記の例の様に変数宣言の構文に 初期値を代入する式が書ける様に成った 其の際 1 の様に単一の値

ICONファイルフォーマット

正規表現応用

ListViewコントロール

ファイル操作-バイナリファイル

構造体

ファイル操作

NotifyIconコントロール

.NETプログラマー早期育成ドリル ~VB編 付録 文法早見表~

VB.NET解説

ファイル監視

データアダプタ概要

プロセス間通信

Userコントロール

DAOの利用

グラフィックス

VB 資料 電脳梁山泊烏賊塾 音声認識 System.Speech の利用 System.Speech に依るディクテーション ( 音声を文字列化 ).NetFramework3.0 以上 (Visual Studio 2010 以降 ) では 標準で System.Speech が用意されて居るの

Microsoft Excel操作

データベースプログラミング

ウィンドウ操作 応用

VB実用⑦ エクセル操作Ⅰ

PYTHON 資料 電脳梁山泊烏賊塾 PYTHON 入門 関数とメソッド 関数とメソッド Python には関数 (function) とメソッド (method) が有る モジュール内に def で定義されて居る物が関数 クラス内に def で定義されて居る物がメソッドに成る ( 正確にはクラスが

モグラ叩きプログラム

PowerPoint プレゼンテーション

正規表現概要

スレッド操作 タイマー

占領双六ゲーム

mySQLの利用

ルーレットプログラム

VB実用Ⅲ⑩ フリーデータベースⅡ

Delphi Generics.Collections

XML(DOMガイド)

プログラミング基礎I(再)

Javaプログラムの実行手順

ブロック パニック

相性占いプログラム

WebBrowserコントロール

インベーダープログラム

相性占いプログラム

回文作成支援プログラム

sinfI2005_VBA.doc

万年暦プログラム

3D回転体プログラム

回文作成支援プログラム

TestDesign for Web

データベースⅠ

文字列操作と正規表現

メール送信

グラフィックス 目次

PowerPoint プレゼンテーション

Java 基礎問題ドリル ~ メソッドを理解する ~ 次のプログラムコードに 各設問の条件にあうメソッドを追加しなさい その後 そのメソッドが正しく動作することを検証するためのプログラムコードを main メソッドの中に追加しなさい public class Practice { // ここに各設問

ブロック崩し風テニス

VB実用③ アクセス操作Ⅰ

ASP.NET 2.0 Provider Model 概要

グラフィックス 目次

万年暦プログラム

チャットアプリ

印刷

intra-mart Accel Platform — IM-Repository拡張プログラミングガイド   初版  

Transcription:

ハッシュテーブル ハッシュテーブル ( 連想配列 ) を使う ハッシュテーブルとは キー (key) と値 (value) のペアを保持して居るコレクションで有る 通常の配列がインデックス番号に依り各値 ( 各要素 ) にアクセス出来るのに比べて ハッシュテーブルでは インデックス番号の代わりにキーを用いて 其の各値にアクセスする事が出来る キーと 其のキーから連想される ( 対応付けられて居る ) 値のペアを保持して居る為 ハッシュテーブルは 連想配列 とも呼ばれる ハッシュテーブルの特長は 指定したキーから 其れに対応した値を高速に得られる事で有る.NET Framework のクラスライブラリでは ハッシュテーブルが Hashtable クラス (System.Collections 名前空間 ) で実装されて居る 本稿では 此の Hashtable クラスの基本的な利用方法に付いて纏める ハッシュテーブルへの項目の追加 ハッシュテーブルへの項目 ( キーと値のペア ) の追加は インデクサ (VB の場合は既定のプロパティとなって居る Item プロパティ ) か Add メソッドに依り行う Dim ht As Hashtable = New Hashtable ht( "japan" ) = " 日本 " ht.add( "china", " 中国 " ) Hashtable ht = new Hashtable( ); ht[ "japan" ] = " 日本 "; ht.add( "china", " 中国 " ); 指定したキーがハッシュテーブル ( 此の例では ht) に存在しない場合には 新しい要素と仕て登録される キーが既に存在する場合には インデクサでは 其のキーに対応する値が置き換えられるが Add メソッドでは例外が発生する 猶 此の例では キーと値の両方に文字列を用いて居るが 実際には Object 型のキーと値が指定可能で有る為 何の様なオブジェクトでも Hashtable オブジェクトに格納出来る ハッシュテーブル内の値の取得 ハッシュテーブル内の値の取得は 上記と同様にインデクサ (VB では Item プロパティ ) に依りキーを指定して行う ( 逆に 値からキーを直接取得する事は出来ない ) 今述べた様に ハッシュテーブルは要素を Object 型のオブジェクトと仕て保持して居る為 必要なら元の型に変換しなければ成らない Dim str As String = CType( ht( "japan" ), String ) string val = ( string )ht[ "japan" ]; 指定したキーがハッシュテーブルに存在しない場合には null(vb では Nothing) が返される -1-

総てのキーや値の列挙 ハッシュテーブルに格納されて居る総てのキー 或るいは 値は コレクションと仕て Keys プロパティ 或るいは Values プロパティからアクセス出来る 此の為 foreach ステートメント (VB では For Each...) 等を使って 総てのキーや値を列挙する事が出来る ( 記述例は下のサンプルプログラムを参照 ) キーや値の存在チェック 特定のキーや値がハッシュテーブルに格納されて居るか何うかは ContainsKey メソッド 或るいは ContainsValue メソッドを使用する 此の 2 つのメソッドは bool 型 (VB では Boolean 型 ) の値 (True か False) を返す ( 記述例は下のサンプルプログラムを参照 ) ハッシュテーブルを使ったサンプルプログラム 此処迄の解説を纏めたサンプルプログラム ( 版及び VB 版 ) を以下に示す Imports System Imports System.Collections Class HashTableSample Shared Sub Main( ) Dim ht As Hashtable = New Hashtable ' データの追加其の 1 ht( "japan" ) = " 日本 " ht( "america" ) = " アメリカ " ' データの追加其の 2 ht.add( "china", " 中国 " ) ht.add( "india", " インド " ) ' データの取得 Dim str As String = CType( ht( "japan" ), String ) Console.WriteLine( str ) ' 出力 : 日本 ' キー項目の列挙 For Each key As String In ht.keys Console.WriteLine("{ 0 : { 1 ", key, ht( key )) ' 出力例 : ' india : インド ' japan : 日本 ' america : アメリカ ' china : 中国 ' 値項目の列挙 For Each val As String In ht.values Console.WriteLine( val ) ' 出力例 : ' インド -2-

' 日本 ' アメリカ ' 中国 ' キーの存在チェック If Not ht.containskey( "france" ) Then ht( "france" ) = " フランス " End If ' 値の存在チェック Console.WriteLine( ht.containsvalue( " アメリカ " )) ' 出力 :True ' エントリ ( キーと値 ) の列挙 For Each de As DictionaryEntry In ht Console.WriteLine("{ 0 : { 1 ", de.key, de.value ) ' 出力例 : ' india : インド ' japan : 日本 ' france : フランス ' america : アメリカ ' china : 中国 End Sub End Class using System; using System.Collections; public class test { static void Main( ) { Hashtable ht = new Hashtable( ); // データの追加其の 1 ht[ "japan" ] = " 日本 "; ht[ "america" ] = " アメリカ "; // データの追加其の 2 ht.add( "china", " 中国 " ); ht.add( "india", " インド " ); // データの取得 string val = ( string )ht[ "japan" ]; Console.WriteLine( val ); // 出力 : 日本 // キー項目の列挙 foreach ( string key in ht.keys) { Console.WriteLine("{ 0 : { 1 ", key, ht[ key ]); // 出力例 : // india : インド // japan : 日本 // america : アメリカ // china : 中国 -3-

// 値項目の列挙 foreach ( string value in ht.values) { Console.WriteLine( value ); // 出力例 : // インド // 日本 // アメリカ // 中国 // キーの存在チェック if (!ht.containskey( "france" )) { ht[ "france" ] = " フランス "; // 値の存在チェック Console.WriteLine( ht.containsvalue( " 日本 " )); // 出力例 :True // エントリ ( キーと値 ) の列挙 foreach ( DictionaryEntry de in ht) { Console.WriteLine("{ 0 : { 1 ", de.key, de.value ); // 出力例 : // india : インド // japan : 日本 // france : フランス // america : アメリカ // china : 中国 サンプルプログラムの最後では ハッシュテーブル内の要素 ( エントリ ) を列挙する方法も示して居る 此の場合には ハッシュテーブル内の各要素は DictionaryEntry 構造体 (System.Collections 名前空間 ) のオブジェクトと仕て取り扱われる 猶通常の配列等と異なり ハッシュテーブルでは格納した要素の順序は保持されない 此の為キーや値や要素を列挙した場合に 何の様な順で要素が取り出されるかは不定で有る 若し キーも値も文字列に限定する事が出来る場合には StringDictionary クラス (System.Collections.Specialized 名前空間 ) も便利に使える 此のクラスは Hashtable クラスをラップし メソッドやプロパティで扱う型を String 型に限定した物で有る -4-

ハッシュテーブル ( 連想配列 ) を使う (Dictionary クラス編 )[2.0] ハッシュテーブルとは キー (key) と値 (value) のペアを保持して居るコレクションで有る 通常の配列やリストがインデックス番号に依り各値 ( 各要素 ) にアクセス出来るのに比べて ハッシュテーブルでは インデックス番号の代わりにキーを用いて 其の各値にアクセスする事が出来る キーと 其のキーから連想される ( キーに対応付けられて居る ) 値のペアを保持して居る為 ハッシュテーブルは 連想配列 とも呼ばれる ハッシュテーブルの特長は 指定したキーから 其れに対応した値を高速に得られる事で有る.NET Framework 1.x のクラスライブラリでは ハッシュテーブルは Hashtable クラス (System.Collections 名前空間 ) で実装されて居たが.NET Framework 2.0 では Dictionary ジェネリッククラス (System.Collections.Generic 名前空間 ) が追加され より効率的 且つ 安全にハッシュテーブルを扱える様に成って居る 本稿では 此の Dictionary ジェネリッククラスの基本的な利用方法に付いて纏める ハッシュテーブルのインスタンス作成 Dictionary ジェネリッククラスは コレクションの要素と成るキーと値の型を型パラメータに依り指定してインスタンスを作成する 以下は キーも値も文字列の場合の記述例で有る Dim dict As New Dictionary( Of String, String ) Dictionary< string, string > dict = new Dictionary< string, string >( ); 此の場合には 以降のハッシュテーブル ( 此の例では dict) への操作で 文字列でないキーや値を扱うコードはコンパイルエラーと成る ハッシュテーブルへの項目の追加 ハッシュテーブルへの項目 ( キーと値のペア ) の追加は インデクサ (VB の場合は既定のプロパティと成って居る Item プロパティ ) か Add メソッドに依り行う dict( "japan" ) = " 日本 " dict( "america" ) = " アメリカ " dict.add( "china", " 中国 " ) dict.add( "india", " インド " ) dict[ "japan" ] = " 日本 "; dict[ "america" ] = " アメリカ "; dict.add( "china", " 中国 " ); dict.add( "india", " インド " ); 指定したキーがハッシュテーブルに存在しない場合には 新しい要素と仕て登録される キーが既に存在する場合には インデクサでは其のキーに対応する値が置き換えられるが Add メソッドでは例外が発生する -5-

ハッシュテーブル内の値の取得 ハッシュテーブル内の或るキーに対する値の取得は 上記と同様にインデクサに依りキーを指定して行う ( 逆に 値からキーを直接取得する事は出来ない ) Hashtable クラスでは取り出した値は Object 型と成る為 通常はキャストが必要と成るが Dictionary ジェネリッククラスではキャストは不要で有る Dim val As String = dict( "japan" ) strin g val = dict[ "japan" ]; 亦 Hashtable クラスでは 指定したキーがハッシュテーブルに存在しない場合には null(vb では Nothing) が返されるが Dictionary ジェネリッククラスでは例外が発生する 此の為 指定したキーが存在するか何うかをチェックし 若し存在すれば其の値を取得する TryGetValue メソッドが Dictionary ジェネリッククラスには追加されて居る ( 記述例は下のサンプルプログラムを参照 ) 総てのキーや値の列挙 ハッシュテーブルに格納されて居る総てのキー 或るいは 値は コレクションと仕て Keys プロパティ 或るいは Values プロパティから取得出来る 此の為 foreach ステートメント (VB では For Each...) 等を使って 総てのキーや値を列挙する事が出来る ( 記述例は下のサンプルプログラムを参照 ) キーや値の存在チェック 特定のキーや値を持つ項目がハッシュテーブルに格納されて居るか何うかを調べるには ContainsKey メソッド 或るいは ContainsValue メソッドを使用する 此の 2 つのメソッドは bool 型 (VB では Boolean 型 ) の値 (True か False) を返す ( 記述例は下のサンプルプログラムを参照 ) 個々の要素の列挙 ハッシュテーブル内の要素を列挙する場合には 各要素は KeyValuePair ジェネリック構造体 (System.Collections.Generic 名前空間 ) のオブジェクトと仕て扱われる 此の構造体は 2 つの型パラメータを持つが 其等は Dictionary ジェネリッククラスのインスタンス作成時に指定した物と同一と成る そして KeyValuePair ジェネリック構造体のオブジェクトからは Key 及び Value プロパティに依りキーと値を取得出来る ( 記述例は下のサンプルプログラムを参照 ) 猶 通常の配列等と異なり ハッシュテーブルでは格納した要素の順序は保持されない 此の為キーや値や要素を列挙した場合に 何の様な順で要素が取り出されるかは不定で有る ハッシュテーブルを使用したサンプルプログラム 此処迄の解説を纏めたサンプルプログラムを以下に示す Imports System Imports System.Collections.Generic Class DictionaryTest Shared Sub Main( ) -6-

Dim dict As New Dictionary( Of String, String ) ' 要素の追加其の 1 dict( "japan" ) = " 日本 " dict( "america" ) = " アメリカ " ' 要素の追加其の 2 dict.add( "china", " 中国 " ) dict.add( "india", " インド " ) ' 値の取得其の 1 Dim val As String = dict( "japan" ) Console.WriteLine( val ) ' 出力 : 日本 ' Dim sss As String = dict( "russia" ) ' 例外発生 ( キーが無い ) ' 値の取得其の 2 Dim value As String = "" If dict.trygetvalue( "america", value ) Then Console.WriteLine( value ) ' 出力 : アメリカ End If ' キーの列挙 For Each key As String In dict.keys Console.WriteLine("{ 0 : { 1 ", key, dict( key )) ' 出力例 : ' japan : 日本 ' america : アメリカ ' china : 中国 ' india : インド ' 値の列挙 For Each v As String in dict.values Console.WriteLine( v ) ' 出力例 : ' 日本 ' アメリカ ' 中国 ' インド ' キーの存在チェック If Not dict.containskey("france") Then dict( "france" ) = " フランス " End If ' 値の存在チェック Console.WriteLine( dict.containsvalue( " 日本 " )) ' 出力 :True ' 項目 ( キーと値 ) の列挙 For Each kvp As KeyValuePair( Of String, String ) In dict Console.WriteLine("{ 0 : {1", kvp.key, kvp.value ) -7-

' 出力例 : ' japan : 日本 ' america : アメリカ ' china : 中国 ' india : インド ' france : フランス ' ソート済みのハッシュテーブルの利用 Dim sdict As New SortedDictionary( Of string, string )( dict ) For Each kvp As KeyValuePair( Of String, String ) In sdict Console.WriteLine("{ 0 : { 1 ", kvp.key, kvp.value ) ' 出力例 : ' america : アメリカ ' china : 中国 ' france : フランス ' india : インド ' japan : 日本 End Sub End Class using System; using System.Collections.Generic; class DictionaryTest { static void Main( ) { Dictionary< string, string > dict = new Dictionary< string, string >( ); // 要素の追加其の 1 dict[ "japan" ] = " 日本 "; dict[ "america" ] = " アメリカ "; // 要素の追加其の 2 dict.add( "china", " 中国 " ); dict.add( "india", " インド " ); // 値の取得其の 1 string val = dict[ "japan" ]; Console.WriteLine( val ); // 出力 : 日本 // string sss = dict[ "russia" ]; // 例外発生 ( キーが無い ) // 値の取得其の 2 string value = ""; if ( dict.trygetvalue( "america", out value )) { Console.WriteLine( value ); // 出力 : アメリカ // キーの列挙 foreach ( string key in dict.keys) { Console.WriteLine("{ 0 : { 1 ", key, dict[ key ]); -8-

// 出力例 : // japan : 日本 // america : アメリカ // china : 中国 // india : インド // 値の列挙 foreach ( string v in dict.values ) { Console.WriteLine( v ); // 出力例 : // 日本 // アメリカ // 中国 // インド // キーの存在チェック if (!dict.containskey( "france" )) { dict[ "france" ] = " フランス "; // 値の存在チェック Console.WriteLine( dict.containsvalue( " 日本 " )); // 出力 :True // 項目 ( キーと値 ) の列挙 foreach ( KeyValuePair< string, string > kvp in dict) { Console.WriteLine("{ 0 : { 1 ", kvp.key, kvp.value ); // 出力例 : の場合に同じ // ソート済みのハッシュテーブルの利用 SortedDictionary< string, string > sdict = new SortedDictionary< string, string >( dict ); foreach ( KeyValuePair< string, string > kvp in sdict ) { Console.WriteLine("{ 0 : { 1 ", kvp.key, kvp.value ); // 出力例 : の場合に同じ 因みに.NET Framework 2.0 のクラスライブラリには キーに依りコレクションの要素が自動的に並べ替えられる SortedDictionary ジェネリッククラス (System.Collections.Generic 名前空間 ) も用意されて居る 上記のサンプルプログラムの最後の部分では 既に存在するハッシュテーブルを基に此のクラスのインスタンスを作成し 其の全要素を列挙して居る 其の出力例から各項目はキーに依りソートされて居るのが分かる -9-

ハッシュテーブル (Dictionary クラス ) を値でソートする [2.0] 前述の ハッシュテーブル ( 連想配列 ) を使う (Dictionary クラス編 ) では Dictionary クラス (System.Collections.Generic 名前空間 ) の利用方法に付いて解説した 其処でも触れて居る様に ハッシュテーブルに格納した要素の順序は保持されない 併し ハッシュテーブルの要素のソート ( 並べ替え ) を行ってから 要素を順に処理し度い場合は良く有る 例えば テキスト内の単語と其の出現頻度をハッシュテーブルに依りカウントしてから 出現頻度の多い順に処理し度い様な場合で有る 前項の最後に有る様に SortedDictionary クラス (System.Collections.Generic 名前空間 ) を使えば コレクションの要素をキー (Key) の値でソートする事は出来る 併し 各キーに対する値 (Value) でのソート方法は標準では用意されて居らず 独自に実装する必要が有る 本稿では Dictionary< string, int > クラス (VB の場合には Dictionary( Of String, Integer ) クラス ) を 要素の値 ( 整数値 ) に依りソートする場合の実装に付いて紹介する List クラスを利用したソート 此処で紹介する方法は 総ての要素の追加が完了したハッシュテーブルの全要素を最初に List クラス (System.Collections.Generic 名前空間 ) にコピーしてから 各要素を其の値でソートする方法で有る 猶 ハッシュテーブルでは 各要素はキーと値のペアから成る KeyValuePair 構造体 (System.Collections.Generic 名前空間 ) のオブジェクトで表される 先ず ハッシュテーブルを List クラスのオブジェクトにコピーするには 次の様に List クラスのコンストラクタにハッシュテーブル (Dictionary オブジェクト ) を指定する丈で良い 此れに依り KeyValuePair オブジェクトを要素に持つリストが作成される Dim list As New List( Of KeyValuePair( Of String, Integer ))( dict ) List< KeyValuePair< string, int >> list = new List< KeyValuePair< string, int >>( dict ); 変数 dict は Dictionary( string, int ) クラス (VB の場合には Dictionary( Of String, Integer ) クラス ) のオブジェクト 次に List クラスの Sort メソッドを使用してリストのソートを行う 本稿では 要素の比較を行うメソッドを示すデリゲート (System 名前空間の Comparison デリゲート ) をパラメータに持つ Sort メソッドを利用して居る ' Value の大きい順にソート list.sort( AddressOf hikaku ) 省略 Function hikaku( _ ByVal kvp1 As KeyValuePair( Of String, Integer ), _ ByVal kvp2 As KeyValuePair( Of String, Integer )) As Integer Return kvp2.value - kvp1.value End Function -10-

// Value の大きい順にソート list.sort( hikaku ); 省略 int hikaku( KeyValuePair< string, int > kvp1, KeyValuePair< string, int > kvp2 ) { return kvp2.value - kvp1.value; 比較を行うメソッド ( 上記コードでは hikaku メソッド ) では メソッドのパラメータで与えられる 2 つの KeyValuePair オブジェクトに付いて 要素の値を示す Value プロパティに依り値の比較を行い 其の結果を 0 より大きい値 0 0 より小さい値の孰れかで返せば良い 以下に 此等を実装したサンプルプログラムを示す ハッシュテーブルを値でソートするサンプルプログラム 此のサンプルプログラムでは @IT のトップページの HTML を取得し 其の内容を単語に分割してから 単語毎の出現頻度をハッシュテーブルに依りカウントする 然して 値に依るソートを実装した sortbyvalue メソッドに依り List オブジェクトを得て 其の各要素を順に画面に出力する Imports System Imports System.Net Imports System.Text.RegularExpressions Imports System.Collections.Generic Class DictionarySortByValue Shared Sub makedict( ByVal dict As Dictionary( Of String, Integer )) Dim html As String ' HTML の取得 Using wc As New WebClient( ) html = wc.downloadstring( "http://www.atmarkit.co.jp/" ) End Using ' 単語に分割して 各単語の出現頻度をカウント For Each s As String In Regex.Split( html, " W" ) Dim word As String = s.trim( ) If Not word = "" Then If dict.containskey( word ) Then dict( word ) += 1 Else dict( word ) = 1 End If End If End Sub -11-

Shared Sub Main( ) Dim dict As New Dictionary( Of String, Integer ) makedict( dict ) Dim sorted As List( Of KeyValuePair( Of String, Integer )) = sortbyvalue( dict ) ' sorted.reverse( ) ' 逆順にする場合 For Each kvp As KeyValuePair( Of String, Integer ) In sorted Console.WriteLine( kvp.key & ":" & kvp.value ) ' 出力例 : ' a:542 ' td:394 ' 0:328 ' width:289 ' tr:284 ' End Sub Shared Function hikaku( _ ByVal kvp1 As KeyValuePair( Of String, Integer ), _ ByVal kvp2 As KeyValuePair( Of String, Integer )) As Integer ' Value の大きい順にソート Return kvp2.value - kvp1.value End Function Shared Function sortbyvalue( _ ByVal dict As Dictionary( Of String, Integer )) _ As List( Of KeyValuePair( Of String, Integer )) Dim list As New List( Of KeyValuePair( Of String, Integer ))( dict ) list.sort( AddressOf hikaku ) Return list End Function End Class using System; using System.Net; using System.Text.RegularExpressions; using System.Collections.Generic; class DictionarySortByValue { static void makedict( Dictionary< string, int > dict ) { string html; // HTML の取得 using ( WebClient wc = new WebClient( )) { html = wc.downloadstring( "http://www.atmarkit.co.jp/" ); // 単語に分割して 各単語の出現頻度をカウント foreach ( string s in Regex.Split( html, " W" )) { -12-

string word = s.trim( ); if ( word!= "" ) { if ( dict.containskey( word )) { dict[ word ]++; else { dict[ word ] = 1; static void Main( ) { Dictionary< string, int > dict = new Dictionary< string, int >( ); makedict( dict ); List< KeyValuePair< string, int >> sorted = sortbyvalue( dict ); // sorted.reverse( ); // 逆順にする場合 foreach ( KeyValuePair< string, int > kvp in sorted ) { Console.WriteLine( kvp.key + ":" + kvp.value ); // 出力例 : // a:542 // td:394 // 0:328 // width:289 // tr:284 // static List< KeyValuePair< string, int >> sortbyvalue( Dictionary< string, int > dict ) { List< KeyValuePair< string, int >> list = new List< KeyValuePair< string, int >>( dict ); // Value の大きい順にソート list.sort( delegate( KeyValuePair< string, int > kvp1, KeyValuePair< string, int > kvp2 ) { return kvp2.value - kvp1.value; ); return list; 猶 版では Sort メソッドのパラメータ部分に匿名メソッドを使用して居る 汎用的な sortbyvalue メソッド 上記サンプルプログラムの sortbyvalue メソッドでは キーが文字列 値が整数値の要素而巳しか扱えないが ジェネリックメソッドの仕組みを用いれば 此れをもう少し汎用的に記述出来る 以下に其の記述例を示して置く -13-

Shared Function hikaku( Of TKey, TValue As IComparable( Of TValue ))( _ ByVal kvp1 As KeyValuePair( Of TKey, TValue ), _ ByVal kvp2 As KeyValuePair( Of TKey, TValue )) As Integer Return kvp2.value.compareto(kvp1.value) End Function Shared Function sortbyvalue( Of TKey, TValue As IComparable( Of TValue ))( _ ByVal dict As Dictionary( Of TKey, TValue )) _ As List(Of KeyValuePair( Of TKey, TValue )) Dim list As New List( Of KeyValuePair( Of TKey, TValue ))( dict ) ' Value の大きい順にソート list.sort( AddressOf hikaku ) Return list End Function static List< KeyValuePair< TKey, TValue >> sortbyvalue< TKey, TValue >( IDictionary< TKey, TValue > dict ) where TValue: IComparable< TValue > { List< KeyValuePair< TKey, TValue >> list = new List< KeyValuePair< TKey, TValue >>( dict ); // Value の大きい順にソート list.sort( delegate( KeyValuePair< TKey, TValue > kvp1, KeyValuePair< TKey, TValue> kvp2 ) { return kvp2.value.compareto( kvp1.value ); ); return list; 此の sortbyvalue メソッドは 要素の値 (Value) の型が IComparable インターフェイス (System 名前空間 ) を実装して居る場合に利用出来る 文字列や基本的な数値型は此のインターフェイスを実装して居る -14-

1 つのキー文字列に対して複数の文字列値を保持 前述に ハッシュテーブル ( 連想配列 ) を使う で解説して居る様に ハッシュテーブル (Hashtable クラス ) では キーと値のペアをコレクションと仕て保持する事が出来る ハッシュテーブルの用途と仕ては 其のキーも値も文字列で有ると謂うケースが多いが 1 つのキー文字列に対して複数の文字列を保持し度い場合には 複数の文字列を 1 つの文字列と仕て連結するか ( 区切り文字が必要 ) 配列や ArrayList オブジェクト等に複数の文字列を格納し 其れをキーに対する値とする等しなければ成らない.NET Framework のクラスライブラリには 此の様な 1 つのキー文字列に対して複数の文字列値を保持する特殊なコレクションが NameValueCollection クラス (System.Collections.Specialized 名前空間 ) と仕て用意されて居る NameValueCollection クラスでは Hashtable クラスと同様に キーと値のペアをコレクションに追加する為に Add メソッドが使用出来るが 既にキーがコレクションに存在する場合には 其れに対する値に文字列が追加される事に成る (Hashtalbe クラスでは例外が発生する ) NameValueCollection nvc = new NameValueCollection( ); nvc.add( " キー 1", " 値 1-1" ); nvc.add( " キー 1", " 値 1-2" ); // nvc は キー 1 に対して 2 つの文字列を保持して居る同じキー文字列に対して複数の文字列値を追加出来る VB のコード例に付いては下記のサンプルプログラムを参照 然して NameValueCollection クラスでは コンマ (, ) で連結された 1 つの文字列か 文字列の配列と仕て コレクションから其の値を取り出す事が出来る NameValueCollection クラスの主要なプロパティやメソッドを使用したサンプルプログラムを以下に示す Imports System Imports System.Collections.Specialized Public Class NameAndValues Shared Sub Main Dim nvc As NameValueCollection = new NameValueCollection( ) ' キーと値の追加 nvc.add( " キー 1", " 値 1-1" ) nvc.add( " キー 1", " 値 1-2" ) nvc.add( " キー 2", " 値 2-1" ) ' キー文字列の取得 ' 総てのキー文字列の取得 Dim keys As String( ) = nvc.allkeys For Each s As String In keys Console.WriteLine( s ) -15-

' 出力 : ' キー 1 ' キー 2 ' インデックス番号に依るキー文字列の取得 Console.WriteLine( nvc.getkey( 0 )) ' 出力 : キー 1 Console.WriteLine( nvc.getkey( 1 )) ' 出力 : キー 2 ' 或るキーの値を文字列配列と仕て取得 ' インデックス番号に依り指定したキーの総ての値を文字列配列と仕て取得 Dim values1 As String( ) = nvc.getvalues( 0 ) For Each s As String In values1 Console.WriteLine( s ) ' 出力 : ' 値 1-1 ' 値 1-2 ' キー文字列に依り指定したキーの総ての値を文字列配列と仕て取得 Dim values2 As String( ) = nvc.getvalues( " キー 1" ) For Each s As String In values2 Console.WriteLine( s ) ' 出力 : ' 値 1-1 ' 値 1-2 ' 或るキーの値をコンマ区切り文字列と仕て取得 ' インデックス番号に依り指定したキーの総ての値をコンマ区切りの文字列と仕て取得 Console.WriteLine( nvc( 0 )) ' 出力 : 値 1-1, 値 1-2 Console.WriteLine( nvc( 1 )) ' 出力 : 値 2-1 ' キー文字列に依り指定したキーの総ての値をコンマ区切りの文字列と仕て取得 Console.WriteLine( nvc( " キー 1" )) ' 出力 : 値 1-1, 値 1-2 Console.WriteLine( nvc( " キー 2" )) ' 出力 : 値 2-1 End Sub End Class using System; using System.Collections.Specialized; public class NameAndValues { static void Main( ) { NameValueCollection nvc = new NameValueCollection( ); // キーと値の追加 nvc.add( " キー 1", " 値 1-1" ); nvc.add( " キー 1", " 値 1-2" ); nvc.add( " キー 2", " 値 2-1" ); -16-

// キー文字列の取得 // 総てのキー文字列の取得 string[ ] keys = nvc.allkeys; foreach ( string s in keys ) { Console.WriteLine( s ); // 出力 : // キー 1 // キー 2 // インデックス番号に依るキー文字列の取得 Console.WriteLine( nvc.getkey( 0 )); // 出力 : キー 1 Console.WriteLine( nvc.getkey( 1 )); // 出力 : キー 2 // 或るキーに対する値を文字列配列と仕て取得 // インデックス番号に依り指定したキーの総ての値を文字列配列と仕て取得 string[ ] values1 = nvc.getvalues( 0 ); foreach ( string s in values1 ) { Console.WriteLine( s ); // 出力 : // 値 1-1 // 値 1-2 // キー文字列に依り指定したキーの総ての値を文字列配列と仕て取得 string[ ] values2 = nvc.getvalues( " キー 1" ); foreach ( string s in values2 ) { Console.WriteLine( s ); // 出力 : // 値 1-1 // 値 1-2 // 或るキーに対する値をコンマ区切り文字列と仕て取得 // インデックス番号に依り指定したキーの総ての値をコンマ区切りの文字列と仕て取得 Console.WriteLine( nvc[ 0 ]); // 出力 : 値 1-1, 値 1-2 Console.WriteLine( nvc[ 1 ]); // 出力 : 値 2-1 // キー文字列に依り指定したキーの総ての値をコンマ区切りの文字列と仕て取得 Console.WriteLine( nvc[ " キー 1" ]); // 出力 : 値 1-1, 値 1-2 Console.WriteLine( nvc[ " キー 2" ]); // 出力 : 値 2-1 猶 NameValueCollection クラスには コレクション内の値の設定 取得する為の Set メソッド Get メソッドが用意されて居るが 此等はインデクサ (VB の場合は既定のプロパティと成って居る Item プロパティ ) で代用出来る為 態々メソッドを使う必要は無い -17-