-
今回は HTML5 で用意されている canvas を使って画像ファイルを描画する方法について説明します。 canvas の使い方ですが、以下の様に順を追って説明します。
■画像の描画
直線の描画を行う為のコンテキストオブジェクトのメソッドは以下のものがあります。
メソッド 書式 説明 drawImage drawImage(image, x, y)
image:画像オブジェクト
x:描画開始の x 座標
y:描画開始の y 座標シンプルな描画 drawImage drawImage(image, x, y, dWidth, dHeight)
image:画像オブジェクト
x:描画開始の x 座標
y:描画開始の y 座標
dWidth:描画する横幅
dHeight:描画する縦幅描画開始位置と縮小幅を指定した描画 drawImage drawImage(image, sx, sy, sWidth, sHeight,
dx, dy, dWidth, dHeight)
image:画像オブジェクト
sx:描画元の x 座標
sy:描画元の y 座標
sWidth:描画する元画像の横幅
sHeight:描画する元画像の縦幅
dx:描画開始の x 座標
dy:描画開始の y 座標
dWidth:描画する横幅
dHeight:描画する縦幅元画像の取り出し位置と幅、及び描画開始位置と幅指定 上記の drawImage の3種類の例として以下のソースを示します。
尚、今回使用した画像ファイルは以下の様なものです。この処理の肝は、イメージオブジェクトへの画像ファイルを指定しす直後には描画処理を行わないことです。
画像ファイルの読込には時間が掛かるので、ファイルのロードが終わったタイミングで描画処理をする必要があります。
ソース上では img1.src = の直後に img1.onload がありますので、勘違いされないないように。
img1.onload ではロード直後に呼ばれる関数を宣言しています。 (実際のファイルロード後この関数が実行されます)<html> <head> <meta charset="utf-8"> <title>test ajax</title> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> <script type="text/javascript"> //Image関数 function drawImage(iSwitch) { var canvas = $("#canvas"); var ctx = canvas[0].getContext("2d"); //イメージオブジェクト var img1 = new Image(); //画像ファイル指定でファイル読込開始 img1.src = "./canvastest1.jpg"; //画像ロード後に画像を描画できる。 img1.onload = function(){ //画像の大きさを設定 width = img1.width; height = img1.height; canvas.attr('width' , width); canvas.attr('height', height); //画像を描画 switch (iSwitch) { case 1: ctx.drawImage(img1, 0, 0); break; case 2: ctx.drawImage(img1, 50, 50, 100, 100); break; case 3: ctx.drawImage(img1, 0, 0, 150, 150, 10, 10, 150, 150); break; } } return false; } </script> </head> <body> <h2>test canvas</h2> <canvas id="canvas" width="200" height="200" ></canvas> <br /> <button onclick="drawImage(1);">開始座標指定のみ</button> <button onclick="drawImage(2);">開始座標,幅指定</button> <button onclick="drawImage(3);">元画像,描画先の指定</button> </body> </html>
■画像の大きさにcanvasを合わせる描画
画像の大きさに合わせて canvas の横と縦の幅を合わせる例を示します。
<html> <head> <meta charset="utf-8"> <title>test ajax</title> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> <script type="text/javascript"> //Image関数 function drawImage(imageFile) { var canvas = $("#canvas"); var ctx = canvas[0].getContext("2d"); //イメージオブジェクト var img1 = new Image(); //画像ファイル指定でファイル読込開始 img1.src = imageFile; //画像ロード後に画像を描画できる。 img1.onload = function(){ //画像の大きさを設定 width = img1.width; height = img1.height; canvas.attr('width' , width); canvas.attr('height', height); //画像を描画 ctx.drawImage(img1, 0, 0, width, height); } return false; } </script> </head> <body> <h2>test canvas</h2> <canvas id="canvas" width="200" height="200" ></canvas> <br /> <button onclick="drawImage('./canvastest1.jpg');">Image1</button> <button onclick="drawImage('./canvastest2.jpg');">Image2</button> </body> </html>
「Image1」をクリックすると上記の画像が表示され、「Image2」をクリックすると少し大きい画像が表示されます。
■ページロード直後の描画
画像ファイルの表示には Img タグを使えばいいのですが、javascript による描画をしたい時があります。 その場合にはページがロードされた直後に canvas への画像を行います。
上記の画像表示関数を流用すれば特に難しくなく、ページロード時の $(function() { でその描画関数を呼出せば行えます。<html> <head> <meta charset="utf-8"> <title>test ajax</title> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> <script type="text/javascript"> //Image関数 function drawImage() { var canvas = $("#canvas"); var ctx = canvas[0].getContext("2d"); //イメージオブジェクト var img1 = new Image(); //画像ファイル指定でファイル読込開始 img1.src = "./canvastest1.jpg"; //画像ロード後に画像を描画できる。 img1.onload = function(){ //画像の大きさを設定 width = img1.width; height = img1.height; canvas.attr('width' , width); canvas.attr('height', height); //画像を描画 ctx.drawImage(img1, 0, 0, width, height); } return false; } $(function() { //描画関数をCALL drawImage(); }); </script> </head> <body> <h2>test canvas</h2> <canvas id="canvas" width="200" height="200" ></canvas> </body> </html>
PR -
今回は HTML5 で用意されている canvas を使って図形を描画する方法について説明します。
この canvas は以前の様に Flash や Java を使わずに JavaScript で図形を描画することができます。
canvas の使い方ですが、以下の様に順を追って説明します。■canvasを使う準備
以下の様に HTML ソースの中に canvas タグを定義します。 タグIDは取敢えず canvas とし width height で領域の大きさを設定します。
その後 javascript で canvas にアクセスする為に canvas オブジェクトを取得します。 さらに canvas オブジェクトからグラフィック用コンテキストオブジェクトを取得します。
コンテキストオブジェクトの中のメソッドを使って各種の描画を行います。<canvas id="canvas" width="200" height="200" ></canvas> ... <script type="text/javascript"> ... var canvas = $("#canvas"); //canvasオブジェクトを取得 var ctx = canvas[0].getContext("2d"); //コンテキストオブジェクトを取得 //"2d":2次元グラフィック ... </script>
■直線の描画
直線の描画を行う為のコンテキストオブジェクトのメソッドは以下のものがあります。
メソッド 書式 説明 beginPath beginPath() 線処理の開始指定 moveTo moveTo(x, y)
x:点の x (水平) 座標
y:点の y (鉛直) 座標点の移動 lineTo lineTo(x, y)
x:線の終点の x 座標
y:線の終点の y 座標現在の点と指定された座標で直線を描画
(この線は実際には描画されません)closePath closePath() beginPathで始めたパスを最後に閉じる
(閉じた図形が描画される)stroke stroke() 現在まで蓄積された描画情報で実際に描画する 直線の例として以下のソースを示します。 closePath の部分がコメントになっていますが、 このまま実行すると、ソースの下の実際のボタンの「Line」の処理となり、 コメントを解除すると三角形を描画する「Triangle」の処理となります。
<html> <head> <meta charset="utf-8"> <title>test ajax</title> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> <script type="text/javascript"> //Line関数 function drawLine() { var canvas = $("#canvas"); var ctx = canvas[0].getContext("2d"); //パス開始 ctx.beginPath(); //パス始点の座標 ctx.moveTo( 10, 10); //線の終点の座標 ctx.lineTo(190,190); //引き続いて線の終点の座標 ctx.lineTo( 10,190); //パス終了 //ctx.closePath(); //パスの輪郭の描画 ctx.stroke(); return false; } </script> </head> <body> <h2>test canvas</h2> <canvas id="canvas" width="200" height="200" ></canvas> <br /> <button onclick="drawLine();">Line</button> </body> </html>
「Line」をクリックすると2本の線が「Triangle」をクリックすると三角形の線が描画されます。
■四角形の描画
四角形の描画を行う為のコンテキストオブジェクトのメソッド・プロパティは以下のものがあります。
メソッド・
プロパティ書式 説明 strokeStyle strokeStyle = color
color:cssで用いる色指示枠線の色指定 strokeRect strokeRect(x, y, width, height)
x:四角形の左上の x (水平) 座標
y:四角形の左上の y (鉛直) 座標
width:四角形の横幅
height:四角形の高さ四角形の描画
線の色は直前のstrokeStyleで指定されたものfillStyle fillStyle = color
color:cssで用いる色指示塗りつぶしの色指定 fillRect fillRect(x, y, width, height)
x:四角形の左上の x (水平) 座標
y:四角形の左上の y (鉛直) 座標
width:四角形の横幅
height:四角形の高さ四角形の描画し内部を塗りつぶす
塗りつぶす色は直前のfillStyleで指定されたものclearRect clearRect(x, y, width, height)
x:四角形の左上の x (水平) 座標
y:四角形の左上の y (鉛直) 座標
width:四角形の横幅
height:四角形の高さ四角形の領域をクリアする 四角形の例として以下のソースを示します。
strokeStyle で線の色を設定し strokeRect で四角い枠を描画します。
fillStyle で塗りつぶす色を設定し fillRect で四角い領域を塗りつぶします。
最後に clearRect で四角い領域をクリアします。<html> <head> <meta charset="utf-8"> <title>test ajax</title> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> <script type="text/javascript"> //Rect関数 function drawRect() { var canvas = $("#canvas"); var ctx = canvas[0].getContext("2d"); //[strokeRect]用色指定 ctx.strokeStyle = "red"; //四角形・枠のみ描画 ctx.strokeRect( 10, 10, 180, 180); //[fillRect]用色指定 ctx.fillStyle = "green"; //四角形・全体を塗りつぶす ctx.fillRect( 50, 50, 100, 100); //四角形・全体をクリア ctx.clearRect( 75, 75, 50, 50); return false; } </script> </head> <body> <h2>test canvas</h2> <canvas id="canvas" width="200" height="200" ></canvas> <br /> <button onclick="drawRect();">Rectangle</button> </body> </html>
「Rectangle」をクリックすると3種類の四角形が描画されます。
■円の描画
円の描画を行う為のコンテキストオブジェクトのメソッド・プロパティは以下のものがあります。
メソッド・
プロパティ書式 説明 arc arc(x, y, radius, startAngle, endAngle [, anticlockwise])
x:円の中心の x (水平) 座標
y:円の中心の y (鉛直) 座標
radius:円の半径
startAngle:円の開始角度(ラジアン:πの値で指定)
endAngle:円の終了角度(ラジアン:πの値で指定)
anticlockwise:trueで時計回り、falseで反時計回りの描画円の描画 <html> <head> <meta charset="utf-8"> <title>test ajax</title> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> <script type="text/javascript"> //Circle関数 function drawCircle() { var canvas = $("#canvas"); var ctx = canvas[0].getContext("2d"); //[strokeRect]用色指定 ctx.strokeStyle = "red"; //[fillRect]用色指定 ctx.fillStyle = "yellow"; //線の幅は3px ctx.lineWidth = 3; //パス開始 ctx.beginPath(); //円描画:中心(100, 100)で半径50pxの円 ctx.arc(100, 100, 50, 0, 2 * Math.PI); //パス終了 ctx.closePath(); //塗りつぶす ctx.fill(); //パスの輪郭の描画 ctx.stroke(); return false; } </script> </head> <body> <h2>test canvas</h2> <canvas id="canvas" width="200" height="200" ></canvas> <br /> <button onclick="drawCircle();">Circle</button> </body> </html>
「Circle」をクリックすると円が描画されます。
-
コレクションクラスの List を For Each 等で要素の削除を行いたい場合があります。 List の要素の削除ぐらい簡単だと思っていたのですが、上手くいかなかった方法と、解決方法について記します。
- 簡単に考えていた List からの要素の削除(Remove)
- 解決方法その1・List を配列の様に扱い最後尾から削除(RemoveAt)
- 解決方法その2・ToArray メソッドと For Each による削除(Remove)
■簡単に考えていた List からの要素の削除(Remove)
List を For Each で要素を順次取得し、その要素値で削除してみました。
以下のソースを見て下さい。Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click ' Listの生成(初期化) Dim list As New List(Of Integer) From {0, 1, 10, 100, 1, 1000, 1, 10000} ' 列挙中に削除する Console.WriteLine("=== Remove ===") For Each i As Integer In list Console.WriteLine("要素値「{0}」の表示", i) If i = 1 Then ' 要素値「1」が削除対象 Console.WriteLine("要素値「{0}」の削除", i) list.Remove(i) End If Next End Sub
実行結果がコンソールには以下様に表示されます。
2番目の要素「1」は削除されたのですが、その直後 Next のところで System.InvalidOperationException のエラーが発生してしまいます。 For Each で要素を順次取得中に List の内容を変更したため内部的に位置がずれ、エラーが発生した様です。=== Remove === 要素値「0」の表示 要素値「1」の表示 要素値「1」の削除
■解決方法その1・List を配列の様に扱い最後尾から削除(RemoveAt)
上記の方法では先頭から削除処理を行ったので内部的にずれが発生しエラーとなったので、 今度は最後尾から削除すれば行けるのではないかと以下のソースの様に変更しました。
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click ' Listの生成(初期化) Dim list As New List(Of Integer) From {0, 1, 10, 100, 1, 1000, 1, 10000} ' 列挙中に削除する Console.WriteLine("=== Remove ===") Dim nVal As Integer Dim i As Integer For i = list.Count - 1 To 0 Step -1 nVal = list.Item(i) Console.Write("{0}番目に取得したListの要素:{1}", i, nVal) If nVal = 1 Then '要素値「1」の削除(Index指定) list.RemoveAt(i) Console.Write("...削除", i) End If Console.WriteLine("") Next Console.WriteLine("=== 削除後 ===") i = 0 For Each nVal In list Console.WriteLine("{0}番目に取得したListの要素:{1}", i, nVal) i += 1 Next End Sub
結果は以下の通りです。最後尾から順次、値が「1」のものが削除され、最後に一覧してみると値が「1」の要素は確かに削除されています。
=== Remove === 7番目に取得したListの要素:10000 6番目に取得したListの要素:1...削除 5番目に取得したListの要素:1000 4番目に取得したListの要素:1...削除 3番目に取得したListの要素:100 2番目に取得したListの要素:10 1番目に取得したListの要素:1...削除 0番目に取得したListの要素:0 === 削除後 === 0番目に取得したListの要素:0 1番目に取得したListの要素:10 2番目に取得したListの要素:100 3番目に取得したListの要素:1000 4番目に取得したListの要素:10000
■解決方法その2・ToArray メソッドと For Each による削除(Remove)
今度は For Each を使うのですが、最初の失敗した方法では無く List を ToArray メソッドにより配列として取得する方法を使います。 ToArray メソッドは List を別の配列として生成し、その配列から順次その要素を取得することになります。
直接 List にアクセスするのではなく、一旦別の配列にしてそれにアクセスするので当初の様にエラーが発生しません。Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click ' Listの生成(初期化) Dim list As New List(Of Integer) From {0, 1, 10, 100, 1, 1000, 1, 10000} ' 列挙中に削除する Console.WriteLine("=== Remove ===") Dim nVal As Integer Dim i As Integer For Each nVal In list.ToArray Console.Write("{0}番目に取得したListの要素:{1}", i, nVal) If nVal = 1 Then '要素値「1」の削除 list.Remove(nVal) Console.Write("...削除", i) End If Console.WriteLine("") Next Console.WriteLine("=== 削除後 ===") i = 0 For Each nVal In list Console.WriteLine("{0}番目に取得したListの要素:{1}", i, nVal) i += 1 Next End Sub
結果は以下の通りです。先頭から順次、値が「1」のものを削除します。 最後に一覧してみると値が「1」の要素は確かに削除されています。
=== Remove === 0番目に取得したListの要素:0 0番目に取得したListの要素:1...削除 0番目に取得したListの要素:10 0番目に取得したListの要素:100 0番目に取得したListの要素:1...削除 0番目に取得したListの要素:1000 0番目に取得したListの要素:1...削除 0番目に取得したListの要素:10000 === 削除後 === 0番目に取得したListの要素:0 1番目に取得したListの要素:10 2番目に取得したListの要素:100 3番目に取得したListの要素:1000 4番目に取得したListの要素:10000
関連する記事
⇒コレクション「List」の使い方について
⇒コレクション「List」と配列の相互変換について
⇒コレクション「Dictionary」の使い方について
⇒コレクション「Dictionary」から配列及び List への変換について
⇒配列の使い方について(Dim, Redim)
⇒配列の使い方の注意点について(コピー, Clone)
⇒配列の範囲指定によるコピー(Array.Copy, Skip, Take)
-
テキストボックスは各種のデータ入力に使いますが、その入力データのエラーチェックを行うことが普通です。
エラーチェックの方法はいろいろありますが、例えばテキストボックス毎にエラーチェックを行ったり、 登録処理などのタイミングで入力項目を一括でエラーチェックを行い、エラーが在った項目の背景色を変えたりすることなどがあります。
今回は、テキストボックスに個別にエラー処理を行った場合にフォーカス移動させたい場合の方法について説明したいと思います。■単純にテキストボックスでエラー処理を行う(「Leave」イベント)
先ずフォーム上に1個のテキストボックスと、2個のボタンを張り付けます。 (以下の図参照) 1個のボタンは btnTest の名前でテキストボックスに入力された文字列を表示します。 もう1個のボタンは btnClose の名前で自分のフォームを閉じる様にします。
処理のソースは以下の通りです。テキストボックスのデータのエラー処理を Leave イベントの中で行っています。
数値チェック標準関数の IsNumeric を使って、エラーの場合にはメッセージを表示し、再度フォーカスをテキストボックスに設定しています。 尚、データをより細かくチェックする場合は自分でチェック処理を用意する必要があります。Public Class frmTextBoxExit '「Leave」イベントで個別の入力チェック Private Sub TextBox1_Leave(sender As Object, e As EventArgs) Handles TextBox1.Leave Dim str As String = Trim(Me.TextBox1.Text) '数値チェック If IsNumeric(str) = False Then MsgBox("数字のみ入力して下さい!") Me.TextBox1.Focus() End If End Sub '「Close」ボタンクリックで自分のウインドウを閉じる Private Sub btnClose_Click(sender As Object, e As EventArgs) Handles btnClose.Click Me.Close() End Sub '「Test」ボタンクリックで入力値を表示する Private Sub btnTest_Click(sender As Object, e As EventArgs) Handles btnTest.Click Dim str As String = Trim(Me.TextBox1.Text) MsgBox("入力文字列:" & str, , "Test Button") End Sub End Class
テキストボックスに数字「123」を入力し「Test」ボタンをクリックすると以下の表示になります。
さらにテキストボックスに数字ではない文字「qq」を入力すると、「Test」「Close」ボタンのどちらをクリックしても以下の表示になります。
ウインドウを閉じようとして「Close」ボタンをクリックしても、ボタンクリックイベントは発生しません。
これは、「Close」ボタンをクリックで一旦フォーカスがボタンに移動するのですが、 その後発生するテキストボックスの「Leave」イベントが走ってフォーカスが強制的に、テキストボックスに戻されてしまうからです。
これでは、このままの状態ではフォームは閉じなくなります。 (テキストボックスの入力を数字にすれば閉じます。また、ウインドウの右上の「×」をクリックすれば閉じますが)
■「Leave」イベントのエラー処理を強制的に抜け出る方法
「Leave」イベントのエラー処理の中では、フォーム上のアクティブなコントロールは、テキストボックスではなく既に「Close」ボタンの方に移っています。 フォーム上のアクティブなコントロールは ActiveControl プロパティに持っています。 このプロパティはフォーム上のアクティブなコントロールの情報を持っています。(と言うかデータ型がControlです)
このプロパティからコントロールの名前を取得し、「btnClose」であればエラー処理をスキップする様にします。
以下に修正したソースを示します。Public Class frmTextBoxExit '「Leave」イベントで個別の入力チェック Private Sub TextBox1_Leave(sender As Object, e As EventArgs) Handles TextBox1.Leave '「アクティブなControl」が「Close」ボタン?? If Me.ActiveControl.Name = "btnClose" Then Exit Sub End If Dim str As String = Trim(Me.TextBox1.Text) '数値チェック If IsNumeric(str) = False Then MsgBox("数字のみ入力して下さい!") Me.TextBox1.Focus() End If End Sub '「Close」ボタンクリックで自分のウインドウを閉じる Private Sub btnClose_Click(sender As Object, e As EventArgs) Handles btnClose.Click Me.Close() End Sub '「Test」ボタンクリックで入力値を表示する Private Sub btnTest_Click(sender As Object, e As EventArgs) Handles btnTest.Click Dim str As String = Trim(Me.TextBox1.Text) MsgBox("入力文字列:" & str, , "Test Button") End Sub End Class
このソースで実行すると、テキストボックスに数字ではない文字を入力しても、「Close」ボタンのクリックでウインドウが閉じます。
■フォーム上の入力データのエラー処理の考察
上記の様にテキストボックスの個別のエラー処理をスキップするには ActiveControl の名前などを確認すればできることが分かりましたが、 他にボタンなどがあれば、それぞれをチェックする必要があります。
尚、他にテキストボックスが在って、それぞれにエラーチェック処理が在る場合は、 それぞれで ActiveControl でボタンの場合エラー処理をスキップする必要があります。
また、フォームの入力データのチェックには一括で行う方法もあります。
「登録」などのボタンを設置して、フォームの入力データを全て取得して、 登録処理等を行うのが一般的だと思いますので、 そのクリックイベントで各入力データ毎に全てのチェック処理を行います。
各データの中でエラーが在ったコントロールにはその証拠となる様に、 背景色などを変更し見た目でエラーが在ったことを表示した方が良いと思います。 (フォーカスは最初にエラーを発見したコントロールに移動すべきです)
最後に、強制的にフォームを閉じる「Close」ボタン等があれば、 フォーム上のデータを1個でも修正したことがあればその旨を表示し 「修正した個所がありますが、フォームを閉じても宜しいでしょうか?」 などのメッセージで聞くことも必要かと思います。関連する記事
⇒テキストボックス拡張クラスにプロパティを追加する方法
⇒フォーム上のコントロールで[Enter]キー押下で次のコントロールにフォーカス移動する
⇒フォーム上のコントロールのイベント処理の一括関連付け:[AddHandler,DirectCast]
⇒コントロールの同じイベント処理に複数の関連付けをテスト:[AddHandler,DirectCast]
-
コレクションクラスの Dictionary は内部的にキー(Keys)と要素(Values)を別々のコレクションとして持っているので、 それぞれ個別に配列に変換ができます。
■Dictionary のキー・要素から配列及び List への変換(ToArray, ToList)
Dictionary のキー(Keys)及び要素(Values)はコレクションとして保持されていて、 そのコレクションとして以下の様なメソッドがあります。
メソッド or
プロパティ書式 説明 ToArray ToArray() As T()
戻り値:
コレクションの内容をそのデータ型の一次元配列を返すコレクションの内容を配列として返す ToList ToList() As List(Of T)
戻り値:
コレクションの内容を List コレクションとして返すコレクションの内容をList コレクションとして返す Count Count As Integer (これはプロパティ) コレクションに存在する要素の数を取得します CopyTo CopyTo(array() As T, index As Integer)
array:コレクションから要素がコピーされる 1次元の System.Array
index:コピーの開始位置で、array 内の 0 から始まるインデックス
例外:ArgumentOutOfRangeException
index が 0 未満
例外:ArgumentException
コレクションの要素数が index からコピー先の array の
末尾までに格納できる数を超えていますコレクション全体を互換性のある1次元の指定したインデックスから配列にコピーします
以下のソースを見て下さい。ToArray, ToList の例を記します。
配列からの要素取得は通常の For で直接要素を指標で指定し、 List の場合には For Each で順次要素を取得します。Private Sub btnList_Click(sender As Object, e As EventArgs) Handles btnList.Click Dim i As Integer = 0 ' Dictionaryの生成(初期化) Dim dic As New Dictionary(Of String, String) From _ {{"USA", "America"}, {"CHN", "China"}, {"JPN", "Japan"}} ' Values(要素の値)を配列へ変換 Dim arrVal() As String Console.WriteLine("=== Values : ToArray ===") arrVal = dic.Values.ToArray() For i = 0 To UBound(arrVal) Console.WriteLine("arrVal({0})の要素:{1}", i, arrVal(i)) Next ' Values(要素の値)を配列へのコピー Console.WriteLine("=== Values : ToList ===") Dim listV As List(Of String) = dic.Values.ToList i = 0 For Each Str As String In listV Console.WriteLine("{0}番目の要素:{1}", i, Str) i += 1 Next ' Keys(キーの値)を配列へ変換 Dim arrKey() As String Console.WriteLine("=== Keys : ToArray ===") arrKey = dic.Keys.ToArray For i = 0 To UBound(arrKey) Console.WriteLine("arrKey({0})の要素:{1}", i, arrKey(i)) Next ' Keys(キーの値)を配列へのコピー Console.WriteLine("=== Keys : ToList ===") Dim listK As List(Of String) = dic.Keys.ToList i = 0 For Each Str As String In listV Console.WriteLine("{0}番目の要素:{1}", i, Str) i += 1 Next End Sub
実行結果がコンソールには以下様に表示されます。
=== Values : ToArray === arrVal(0)の要素:America arrVal(1)の要素:China arrVal(2)の要素:Japan === Values : ToList === 0番目の要素:America 1番目の要素:China 2番目の要素:Japan === Keys : ToArray === arrKey(0)の要素:USA arrKey(1)の要素:CHN arrKey(2)の要素:JPN === Keys : ToList === 0番目の要素:USA 1番目の要素:CHN 2番目の要素:JPN
■Dictionary のメソッド CopyTo について
CopyTo メソッドは指定した配列のインデックスからコレクションをコピーします。
以下の例では、最初のディクショナリを ToArray により配列に変換後、2番目のディクショナリをその配列の直後にコピーしています。 コピーする前に配列の要素数を拡張しています。Private Sub btnList_Click(sender As Object, e As EventArgs) Handles btnList.Click Dim i As Integer = 0 ' Dictionaryの生成(初期化) Dim dic As New Dictionary(Of String, String) From _ {{"USA", "America"}, {"CHN", "China"}, {"JPN", "Japan"}} Dim dic2 As New Dictionary(Of String, String) From _ {{"FRA", "France"}, {"IRL", "Ireland"}, {"THA", "Thailand"}, {"BTN", "Bhutan"}} ' Values(要素の値)を配列へ変換 Dim arrVal() As String Console.WriteLine("=== Values : ToArray ===") arrVal = dic.Values.ToArray() For i = 0 To UBound(arrVal) Console.WriteLine("arrVal({0})の要素:{1}", i, arrVal(i)) Next ' Values(要素の値)を配列へのコピー Console.WriteLine("=== Values : CopyTo ===") Dim idxMax As Integer = UBound(arrVal) ReDim Preserve arrVal(idxMax + dic2.Values.Count) dic2.Values.CopyTo(arrVal, idxMax + 1) For i = 0 To UBound(arrVal) Console.WriteLine("arrVal({0})の要素:{1}", i, arrVal(i)) Next ' Keys(要素の値)を配列へ変換 Dim arrKey() As String Console.WriteLine("=== Keys : ToArray ===") arrKey = dic.Keys.ToArray For i = 0 To UBound(arrKey) Console.WriteLine("arrKey({0})の要素:{1}", i, arrKey(i)) Next ' Values(要素の値)を配列へのコピー Console.WriteLine("=== Keys : CopyTo ===") idxMax = UBound(arrKey) ReDim Preserve arrKey(idxMax + dic2.Keys.Count) dic2.Keys.CopyTo(arrKey, idxMax + 1) For i = 0 To UBound(arrKey) Console.WriteLine("arrKey({0})の要素:{1}", i, arrKey(i)) Next End Sub
結果は以下の通りです。
=== Values : ToArray === arrVal(0)の要素:America arrVal(1)の要素:China arrVal(2)の要素:Japan === Values : CopyTo === arrVal(0)の要素:America arrVal(1)の要素:China arrVal(2)の要素:Japan arrVal(3)の要素:France arrVal(4)の要素:Ireland arrVal(5)の要素:Thailand arrVal(6)の要素:Bhutan === Keys : ToArray === arrKey(0)の要素:USA arrKey(1)の要素:CHN arrKey(2)の要素:JPN === Keys : CopyTo === arrKey(0)の要素:USA arrKey(1)の要素:CHN arrKey(2)の要素:JPN arrKey(3)の要素:FRA arrKey(4)の要素:IRL arrKey(5)の要素:THA arrKey(6)の要素:BTN
関連する記事
⇒コレクション「List」の使い方について
⇒コレクション「List」と配列の相互変換について
⇒配列の使い方について(Dim, Redim)
⇒配列の使い方の注意点について(コピー, Clone)
⇒配列の範囲指定によるコピー(Array.Copy, Skip, Take)