2012-02-06T05:42:45の更新内容

programming/netfx/arrays/0_abstract/index.wiki.txt

current previous
1,512 0,0
+
${smdncms:title,配列の宣言・作成・基本操作}
+
${smdncms:keywords,基本操作,宣言,作成,初期化,列挙,for,foreach,1次元配列,IndexOutOfRangeException}
+
${smdncms:document_versions,codelang=cs,codelang=vb}
+

          
+
#navi(..)
+

          
+
配列とは同じデータ型の要素が集まったデータ構造で、固定長の集合・ベクトルです。 ここでは配列の宣言・作成方法と、配列を使った基本的な操作について見ていきます。 要素の検索やリサイズなどの操作については[[programming/netfx/arrays/2_operations]]で解説します。
+

          
+
なお、ここでは次元のない配列(1次元配列)のみを扱います。 多次元配列については[[programming/netfx/arrays/1_multidimensional]]で追って解説します。 また可変長のデータ構造として[[リスト>programming/netfx/collections/2_generic_1_list]]などの[[コレクション>programming/netfx/collections]]なども存在しますが、ここでは扱いません。
+

          
+
-関連するページ
+
--[[programming/vb.net/basics/05_array]]
+
--[[programming/netfx/collections]]
+
---[[programming/netfx/collections/0_abstract]]
+
---[[programming/netfx/collections/2_generic_1_list]]
+
--[[programming/netfx/enumeration]]
+

          
+
#googleadunit(banner)
+

          
+

          
+

          
+
*配列の作成
+
言語によって構文に多少の違いはありますが、配列を作成するには、次のように格納される要素の型と格納できる要素数(配列の長さ)を指定して行います。 構文は似通っていますが、C#では''格納できる要素数''、VBでは''インデックスの最大値''を指定するという間違いやすい相違点があるので注意が必要です。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 長さが3(格納できる要素数が3)の文字列型配列を作成
+
    string[] arr1 = new string[3];
+

          
+
    // 長さが12(格納できる要素数が12)のint型配列を作成
+
    int[] arr2 = new int[12];
+

          
+
    // 長さが0(格納できる要素数が0)のint型配列を作成
+
    int[] arr3 = new int[0];
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 長さが3(インデックスの最大値が2)の文字列型配列を作成
+
    Dim arr1(2) As String
+

          
+
    ' 長さが12(インデックスの最大値が11)のInteger型配列を作成
+
    Dim arr2(11) As Integer
+

          
+
    ' 長さが0(インデックスの最大値が-1)のInteger型配列を作成
+
    Dim arr3(-1) As Integer
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
必要となるケースは稀ですが、上記の例のように長さ・要素数が0の配列(要素を格納できない配列)も作成することが出来ます。 長さ・要素数を0には出来ますが、当然マイナスにすることは出来ません。
+

          
+

          
+

          
+
*要素の参照
+
.NET Frameworkにおける配列では、要素のインデックス(通番・要素の番号)は0を基準とします。 最初の要素のインデックスは0、その次の要素のインデックスは1、さらにその次は2…、となります。 以降の解説でも、0番目とは最初の要素を指すものとして説明していきます。 C#では配列の変数に続けてかぎ括弧 ''[ ]''、VBでは丸括弧 ''( )''を使ってインデックスを指定します。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 長さが3(格納できる要素数が3)の文字列型配列を作成
+
    string[] users = new string[3];
+

          
+
    users[0] = "Alice";     // 配列の0番目(最初)の要素として"Alice"を設定
+
    users[1] = "Bob";       // 配列の1番目の要素として"Bob"を設定
+
    users[2] = "Charlie";   // 配列の2番目(最後)の要素として"Charlie"を設定
+

          
+
    // 配列の1番目に格納されているの値を表示
+
    Console.WriteLine(users[1]);
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 長さが3(インデックスの最大値が2)の文字列型配列を作成
+
    Dim users(2) As String
+

          
+
    users(0) = "Alice"    ' 配列の0番目(最初)の要素として"Alice"を設定
+
    users(1) = "Bob"      ' 配列の1番目の要素として"Bob"を設定
+
    users(2) = "Charlie"  ' 配列の2番目(最後)の要素として"Charlie"を設定
+

          
+
    ' 配列の1番目に格納されているの値を表示
+
    Console.WriteLine(users(1))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
Bob
+
}}
+

          
+
配列は固定長であり、配列を作成するときに格納できる要素数が決定されます。 配列の長さ(格納できる要素数)を越えるインデックスを指定すると実行時に例外&msdn(netfx,type,System.IndexOutOfRangeException){IndexOutOfRangeException};がスローされます。 配列が自動的に拡張されるといったことは行われません。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 長さが3(格納できる要素数が3)の文字列型配列を作成
+
    string[] users = new string[3];
+

          
+
    users[2] = "Charlie";   // 配列の2番目(最後)の要素として"Charlie"を設定 (問題なく動作する)
+
    users[3] = "Dave";      // 配列の3番目(最後の一つ後)の要素として"Dave"を設定 (インデックスが範囲外のため例外がスローされる)
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 長さが3(インデックスの最大値が2)の文字列型配列を作成
+
    Dim users(2) As String
+

          
+
    users(2) = "Charlie"  ' 配列の2番目(最後)の要素として"Charlie"を設定 (例外がスローされる)
+
    users(3) = "Dave"     ' 配列の3番目(最後の一つ後)の要素として"Dave"を設定 (インデックスが範囲外のため例外がスローされる)
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
ハンドルされていない例外: System.IndexOutOfRangeException: インデックスが配列の境界外です。
+
   場所 Sample.Main()
+
}}
+

          
+
なお、可変長の配列としては[[List>programming/netfx/collections/2_generic_1_list]]が用意されているのでこれを使うことが出来ます。
+

          
+

          
+

          
+
*長さの取得
+
実行時に配列の長さ(配列の要素数・サイズ)を取得するには、&msdn(netfx,member,System.Array.Length){Lengthプロパティ};を参照します。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 長さが3の配列
+
    string[] arr1 = new string[3];
+

          
+
    // 長さが12の配列
+
    int[] arr2 = new int[12];
+

          
+
    // 長さが0の配列
+
    double[] arr3 = new double[0];
+

          
+
    // それぞれの配列の長さを取得して表示
+
    Console.WriteLine("arr1.Length = {0}", arr1.Length);
+
    Console.WriteLine("arr2.Length = {0}", arr2.Length);
+
    Console.WriteLine("arr3.Length = {0}", arr3.Length);
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 長さが3の配列
+
    Dim arr1(2) As String
+

          
+
    ' 長さが12の配列
+
    Dim arr2(11) As Integer
+

          
+
    ' 長さが0の配列
+
    Dim arr3(-1) As Double
+

          
+
    ' それぞれの配列の長さを取得して表示
+
    Console.WriteLine("arr1.Length = {0}", arr1.Length)
+
    Console.WriteLine("arr2.Length = {0}", arr2.Length)
+
    Console.WriteLine("arr3.Length = {0}", arr3.Length)
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
arr1.Length = 3
+
arr2.Length = 12
+
arr3.Length = 0
+
}}
+

          
+

          
+

          
+

          
+
*配列の宣言と初期化
+
ここまでで紹介した例では、配列変数の宣言と、配列の作成・代入を同時に行っていました。 ここでは配列の宣言と作成・初期化の方法を分けて見ていきます。 まず、配列の宣言について見ていきます。 配列を格納する変数を宣言するには、次のようにします。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    string[] arr1;  // string型の配列を格納する変数
+
    int[] arr2;     // int型の配列を格納する変数
+
    double[] arr3;  // double型の配列を格納する変数
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+

          
+
    Dim arr1 As String()  ' String型の配列を格納する変数
+
    Dim arr2 As Integer() ' Integer型の配列を格納する変数
+
    Dim arr3 As Double()  ' Double型の配列を格納する変数
+

          
+
    ' 次のように丸括弧を変数名の後ろに付けても同じ
+
    'Dim arr1() As String  ' String型の配列を格納する変数
+
    'Dim arr2() As Integer ' Integer型の配列を格納する変数
+
    'Dim arr3() As Double  ' Double型の配列を格納する変数
+

          
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
このようにして宣言した変数は、配列が格納できる変数が用意されるだけで、実際にはどの配列も参照していない(配列の実体を参照していない)状態となっています。 C#では未初期化の変数、VBではヌル参照の変数となります。 ここからさらに配列を作成して代入したり、他の変数が参照している配列やメソッドの戻り値として返される配列などを代入したりする必要があります。 なお、VBでは丸括弧を変数名の後ろに付けても、型名の後ろにつけても同じものとして扱われます。
+

          
+
続いて配列の初期化について見ていきます。 次のようにすることで、配列変数の宣言と同時にその変数に格納する配列を作成することが出来ます。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 長さが3の配列を作成し、各要素にそれぞれ文字列"Alice", "Bob", "Charlie"を設定する
+
    string[] arr1 = new string[3] {"Alice", "Bob", "Charlie"};
+
    string[] arr2 = new string[] {"Alice", "Bob", "Charlie"};
+
    string[] arr3 = {"Alice", "Bob", "Charlie"};
+

          
+
    // 長さが5の配列を作成し、各要素にそれぞれ数値0, 1, 2, 3, 4を設定する
+
    int[] arr4 = new int[5] {0, 1, 2, 3, 4};
+
    int[] arr5 = new int[] {0, 1, 2, 3, 4};
+
    int[] arr6 = {0, 1, 2, 3, 4};
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+

          
+
    ' 長さが3の配列を作成し、各要素にそれぞれ文字列"Alice", "Bob", "Charlie"を設定する
+
    Dim arr1 As String() = New String(2) {"Alice", "Bob", "Charlie"}
+
    Dim arr2 As String() = New String() {"Alice", "Bob", "Charlie"}
+
    Dim arr3 As String() = {"Alice", "Bob", "Charlie"}
+

          
+
    ' 長さが5の配列を作成し、各要素にそれぞれ数値0, 1, 2, 3, 4を設定する
+
    Dim arr4 As Integer() = New Integer(4) {0, 1, 2, 3, 4}
+
    Dim arr5 As Integer() = New Integer() {0, 1, 2, 3, 4}
+
    Dim arr6 As Integer() = {0, 1, 2, 3, 4}
+

          
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
このコードにおいて、arr1, arr2, arr3はすべて同じ長さで同じ内容が格納された配列となります。 arr4, arr5, arr6も同様です。 このコードのnew以降の部分は''配列作成式''、中括弧 ''{ }'' の部分は''配列初期化子''と呼ばれます。 配列作成式で配列の長さを指定する場合、配列初期化子で記述されている要素数と合っていないとコンパイルエラーとなります。
+

          
+
配列初期化子を記述しない場合は、指定された長さの配列が作成されますが、作成される配列内の各要素にはデフォルト値が設定されます。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    string[] arr1 = new string[3];  // 長さが3のstring型配列
+
    int[] arr2 = new int[5];        // 長さが5のint型配列
+
    double[] arr3 = new double[12]; // 長さが12のdouble型配列
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+

          
+
    Dim arr1 As String() = New String(2) {}   ' 長さが3のString型配列
+
    Dim arr2 As Integer() = New Integer(4) {} ' 長さが5のInteger型配列
+
    Dim arr3 As Double() = New Double(11) {}  ' 長さが12のDouble型配列
+

          
+
    ' 次のように記述しても同じ
+
    'Dim arr1(2) As String   ' 長さが3のString型配列
+
    'Dim arr2(4) As Integer  ' 長さが5のInteger型配列
+
    'Dim arr3(11) As Double  ' 長さが12のDouble型配列
+

          
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
デフォルト値は型によって異なりますが、数値などの型では0や0に相当する値、文字列型を含む参照型ではヌル参照(null/Nothing)となります。 型とデフォルト値の詳細については[[programming/netfx/basictypes]]を参照してください。
+

          
+
なお、長さ0の配列を作成したい場合は次のように記述することが出来ます。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    string[] arr1 = new string[0];
+
    string[] arr2 = new string[] {};
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+

          
+
    Dim arr1 As String() = New String(-1) {}
+
    Dim arr2 As String() = New String() {}
+
    Dim arr3(-1) As String
+

          
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+

          
+

          
+
*代入
+
配列は参照型であるため、配列の変数に代入を行う場合、''配列がコピーされて代入されるのではなく配列への参照が代入される''という点に注意が必要です。 次の例のように配列の変数に代入を行っても配列の実体は一つであるため、異なる変数を経由した変更でも実際に行われる変更は同一の配列に対するものとなります。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 配列を作成してarr1に代入
+
    string[] arr1 = {"Alice", "Bob", "Charlie"};
+

          
+
    // arr1の各要素を表示
+
    Console.WriteLine("arr1[0] = {0}", arr1[0]);
+
    Console.WriteLine("arr1[1] = {0}", arr1[1]);
+
    Console.WriteLine("arr1[2] = {0}", arr1[2]);
+
    Console.WriteLine();
+

          
+
    // arr1に代入されている配列への参照をarr2に代入
+
    string[] arr2 = arr1;
+

          
+
    arr2[1] = "Dave"; // arr2の1番目の値を変更
+

          
+
    // arr1の各要素を表示
+
    Console.WriteLine("arr1[0] = {0}", arr1[0]);
+
    Console.WriteLine("arr1[1] = {0}", arr1[1]);
+
    Console.WriteLine("arr1[2] = {0}", arr1[2]);
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 配列を作成してarr1に代入
+
    Dim arr1 As String() = {"Alice", "Bob", "Charlie"}
+

          
+
    ' arr1の各要素を表示
+
    Console.WriteLine("arr1(0) = {0}", arr1(0))
+
    Console.WriteLine("arr1(1) = {0}", arr1(1))
+
    Console.WriteLine("arr1(2) = {0}", arr1(2))
+
    Console.WriteLine()
+

          
+
    ' arr1に代入されている配列への参照をarr2に代入
+
    Dim arr2 As String() = arr1
+

          
+
    arr2(1) = "Dave" ' arr2の1番目の値を変更
+

          
+
    ' arr1の各要素を表示
+
    Console.WriteLine("arr1(0) = {0}", arr1(0))
+
    Console.WriteLine("arr1(1) = {0}", arr1(1))
+
    Console.WriteLine("arr1(2) = {0}", arr1(2))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
arr1[0] = Alice
+
arr1[1] = Bob
+
arr1[2] = Charlie
+

          
+
arr1[0] = Alice
+
arr1[1] = Dave
+
arr1[2] = Charlie
+
}}
+

          
+
なお、配列のコピーを行いたい場合は[[Array.Cloneメソッド>programming/netfx/arrays/2_operations#Array.Clone]]または[[Array.Copyメソッド>programming/netfx/arrays/2_operations#Array.Copy]]を使います。
+

          
+

          
+

          
+
*要素の列挙
+
配列内の各要素を列挙するには、for文とforeach文が使えます。 for文では配列のインデックスを使って各要素を参照するのに対し、foreach文では列挙子を使って各要素を参照します。 列挙子とforeach文の関係については[[programming/netfx/enumeration]]で詳しく解説しています。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 配列を作成
+
    string[] arr = {"Alice", "Bob", "Charlie"};
+

          
+
    // for文を使って配列内の各要素を列挙
+
    for (int i = 0; i < arr.Length; i++)
+
    {
+
      Console.WriteLine("arr[{0}] = {1}", i, arr[i]);
+
    }
+

          
+
    Console.WriteLine();
+

          
+
    // foreach文を使って配列内の各要素を列挙
+
    foreach (string elem in arr)
+
    {
+
      Console.WriteLine(elem);
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 配列を作成
+
    Dim arr As String() = {"Alice", "Bob", "Charlie"}
+

          
+
    ' Forステートメントを使って配列内の各要素を列挙
+
    For i As Integer = 0 To arr.Length - 1
+
      Console.WriteLine("arr({0}) = {1}", i, arr(i))
+
    Next
+

          
+
    Console.WriteLine()
+

          
+
    ' For Eachステートメントを使って配列内の各要素を列挙
+
    For Each elem As String In arr
+
      Console.WriteLine(elem)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
arr[0] = Alice
+
arr[1] = Bob
+
arr[2] = Charlie
+

          
+
Alice
+
Bob
+
Charlie
+
}}
+

          
+
foreach文では常に配列の先頭から一つずつ列挙されるため、配列の末尾から先頭に向けて列挙したり、一つ飛ばしで列挙したりといったことは出来ません。 そういった列挙が必要な場合はforeach文ではなくfor文を使って記述する必要があります。 言い換えるなら、列挙する際に要素の位置(インデックス)が重要な場合はfor文、位置は重要でない場合はforeach文というように使い分けることが出来ます。
+

          
+
なお、配列内の要素の順番を逆にしたい場合は[[Array.Reverseメソッド>programming/netfx/arrays/2_operations#Array.Reverse]]を使うことが出来ます。
+

          
+

          
+

          
+
#navi(..)
+

          

programming/netfx/arrays/2_operations/index.wiki.txt

current previous
1,1664 0,0
+
${smdncms:title,Arrayクラス}
+
${smdncms:header_title,Arrayクラス (System.Array)}
+
${smdncms:keywords,クリア,リサイズ,リバース,複製,複写,コピー,検索,Clear,Resize,Reverse,Clone,Copy,CopyTo,IndexOf,Find,RankException}
+
${smdncms:document_versions,codelang=cs,codelang=vb}
+

          
+
#navi(..)
+

          
+
.NET Frameworkにおける配列は&msdn(netfx,type,System.Array){Arrayクラス};を基本クラスとしていて、すべての配列は暗黙的にこのクラスを継承しています。 配列の基本的な機能はすべてこのクラスにより提供されます。 また、&msdn(netfx,type,System.Array){Arrayクラス};には様々なメソッドが用意されていて、それらを使うことで言語の構文では用意されていない配列操作などを行うことが出来ます。
+

          
+
-関連するページ
+
--[[programming/netfx/collections]]
+
--[[programming/netfx/sorting]]
+
--[[programming/netfx/fcl/System.ArraySegment]]
+

          
+
#googleadunit(banner)
+

          
+

          
+

          
+
*クリア (Clear) [#Array.Clear]
+
&msdn(netfx,member,System.Array.Clear){Array.Clearメソッド};を使うことで、配列内の要素をクリアして初期化することが出来ます。 このメソッドを使って配列内をクリアすると、配列内の各要素にデフォルト値が設定されます。 デフォルト値は型によって異なりますが、数値などの型では0や0に相当する値、文字列型を含む参照型ではヌル参照(null/Nothing)となります。 型とデフォルト値の詳細については[[programming/netfx/basictypes]]を参照してください。
+

          
+
また、このメソッドは引数としてクリアを開始するインデックスと長さをとるため、配列の一部分だけをクリアすることも出来ます。 なお、このメソッドでは配列内の要素がクリアされるだけで、配列の長さは変化しません。
+

          
+
#tabpage(C#)
+
#code(cs,1次元配列のクリア){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    int[] arr = {0, 1, 2, 3, 4};
+

          
+
    // インデックスが3の要素から2個分をクリア
+
    Array.Clear(arr, 3, 2);
+

          
+
    foreach (int elem in arr) {
+
      Console.Write("{0}, ", elem);
+
    }
+
    Console.WriteLine();
+

          
+
    // 配列の全要素をクリア
+
    Array.Clear(arr, 0, arr.Length);
+

          
+
    foreach (int elem in arr) {
+
      Console.Write("{0}, ", elem);
+
    }
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,1次元配列のクリア){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim arr() As Integer = {0, 1, 2, 3, 4}
+

          
+
    ' インデックスが3の要素から2個分をクリア
+
    Array.Clear(arr, 3, 2)
+

          
+
    For Each elem As Integer In arr
+
      Console.Write("{0}, ", elem)
+
    Next
+
    Console.WriteLine()
+

          
+
    ' 配列の全要素をクリア
+
    Array.Clear(arr, 0, arr.Length)
+

          
+
    For Each elem As Integer In arr
+
      Console.Write("{0}, ", elem)
+
    Next
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
0, 1, 2, 0, 0, 
+
0, 0, 0, 0, 0, 
+
}}
+

          
+
Array.Clearメソッドでジャグ配列をクリアする場合は、ジャグ配列の1段目に格納されている配列がクリアされヌル参照(null/Nothing)の状態になります。
+

          
+
一方、Array.Clearメソッドで多次元配列をクリアすることも出来ますが、その際多次元配列は1次元配列の様に扱われます。 Array.Clearメソッドの引数に指定するインデックスは、多次元配列を1次元配列に展開したときの位置として解釈されるという点に注意が必要です。
+

          
+
#tabpage(C#)
+
#code(cs,2次元配列のクリア){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    int[,] matrix = {
+
      {0, 1, 2, 3},
+
      {4, 5, 6, 7},
+
      {8, 9, 10, 11},
+
    };
+

          
+
    // 2次元配列の一部分をクリア
+
    Array.Clear(matrix, 3, 4);
+

          
+
    for (int d1 = 0; d1 < matrix.GetLength(0); d1++) {
+
      for (int d2 = 0; d2 < matrix.GetLength(1); d2++) {
+
        Console.Write("{0}, ", matrix[d1, d2]);
+
      }
+
      Console.WriteLine();
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,2次元配列のクリア){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim matrix As Integer(,) = { _
+
      {0, 1, 2, 3}, _
+
      {4, 5, 6, 7}, _
+
      {8, 9, 10, 11} _
+
    }
+

          
+
    ' 2次元配列の一部分をクリア
+
    Array.Clear(matrix, 3, 4)
+

          
+
    For d1 As Integer = 0 To matrix.GetLength(0) - 1
+
      For d2 As Integer = 0 To matrix.GetLength(1) - 1
+
        Console.Write("{0}, ", matrix(d1, d2))
+
      Next
+
      Console.WriteLine()
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
0, 1, 2, 0, 
+
0, 0, 0, 7, 
+
8, 9, 10, 11,
+
}}
+

          
+

          
+

          
+
*リサイズ (Resize) [#Array.Resize]
+
&msdn(netfx,member,System.Array.Resize){Array.Resizeメソッド};を使うことで、配列の長さを変更することが出来ます。 このメソッドによってリサイズされるというのは見た目の動作で、実際には、変更後のサイズの配列が新たに作成され、その配列に元の配列の内容をコピーしたものが引数で指定した配列と置き換えられるという動作になります。 このメソッドでは、配列の長さを元の長さよりも短くすることも長くすることも可能です。 Array.Resizeメソッドで配列を拡張した場合、拡張した部分にはデフォルト値がセットされます。
+

          
+
#tabpage(C#)
+
#code(cs,配列のリサイズ){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    int[] arr = {0, 1, 2, 3, 4};
+

          
+
    // 配列の長さを長くする
+
    Array.Resize(ref arr, 7);
+

          
+
    foreach (int elem in arr) {
+
      Console.Write("{0}, ", elem);
+
    }
+
    Console.WriteLine();
+

          
+
    // 配列の長さを短くする
+
    Array.Resize(ref arr, 3);
+

          
+
    foreach (int elem in arr) {
+
      Console.Write("{0}, ", elem);
+
    }
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,配列のリサイズ){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim arr() As Integer = {0, 1, 2, 3, 4}
+

          
+
    ' 配列の長さを長くする
+
    Array.Resize(arr, 7)
+

          
+
    For Each elem As Integer In arr
+
      Console.Write("{0}, ", elem)
+
    Next
+
    Console.WriteLine()
+

          
+
    ' 配列の長さを短くする
+
    Array.Resize(arr, 3)
+

          
+
    For Each elem As Integer In arr
+
      Console.Write("{0}, ", elem)
+
    Next
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
0, 1, 2, 3, 4, 0, 0, 
+
0, 1, 2, 
+
}}
+

          
+
ジャグ配列をリサイズすることも出来ますが、その場合は1段目の長さのみが変更できます。 2段目以降の長さを変更する場合は、格納されている配列に対して個別にArray.Resizeメソッドを呼び出してリサイズする必要があります。
+

          
+
なお、Array.Resizeメソッドでは多次元配列のサイズを変更することは出来ません。
+

          
+

          
+

          
+
*複製・複写
+
**複製 (Clone) [#Array.Clone]
+
&msdn(netfx,member,System.Array.Clone){Array.Cloneメソッド};を使うことで、配列を複製して同じ内容を持った配列を生成することが出来ます。 Array.Cloneメソッドの戻り値はobjectであるため、必要に応じて複製元と同じ型にキャストして使います。
+

          
+
#tabpage(C#)
+
#code(cs,1次元配列の複製){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    int[] arr1 = {0, 1, 2, 3, 4};
+
    int[] arr2;
+

          
+
    // arr1を複製してarr2に代入
+
    arr2 = (int[])arr1.Clone();
+

          
+
    // 複製元と複製後の配列の要素を変更
+
    arr1[2] = 0;
+
    arr2[2] = 5;
+

          
+
    // それぞれの配列の内容を表示
+
    foreach (int elem in arr1) {
+
      Console.Write("{0}, ", elem);
+
    }
+
    Console.WriteLine();
+

          
+
    foreach (int elem in arr2) {
+
      Console.Write("{0}, ", elem);
+
    }
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,1次元配列の複製){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim arr1() As Integer = {0, 1, 2, 3, 4}
+
    Dim arr2() As Integer
+

          
+
    ' arr1を複製してarr2に代入
+
    arr2 = DirectCast(arr1.Clone(), Integer())
+

          
+
    ' 複製元と複製後の配列の要素を変更
+
    arr1(2) = 0
+
    arr2(2) = 5
+

          
+
    ' それぞれの配列の内容を表示
+
    For Each elem As Integer In arr1
+
      Console.Write("{0}, ", elem)
+
    Next
+
    Console.WriteLine()
+

          
+
    For Each elem As Integer In arr2
+
      Console.Write("{0}, ", elem)
+
    Next
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
0, 1, 0, 3, 4, 
+
0, 1, 5, 3, 4, 
+
}}
+

          
+
このメソッドでは''簡易コピー''が行われるため、参照型を要素に持つ配列では参照のみがコピーされます。 そのため、ジャグ配列の複製を行うと、複製元と複製後のジャグ配列内における2段目以降はどちらも同一のインスタンスを参照する事になります。 Cloneメソッドと簡易コピーについてより詳しくは[[programming/netfx/cloning]]で解説しています。
+

          
+
多次元配列を複製する場合の結果は1次元配列を複製する場合と同様で、長さ・次元数・格納される要素が同一の多次元配列が生成されます。
+

          
+
#tabpage(C#)
+
#code(cs,2次元配列の複製){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    int[,] matrix1 = {
+
      {0, 1, 2, 3},
+
      {4, 5, 6, 7},
+
      {8, 9, 10, 11},
+
    };
+
    int[,] matrix2;
+

          
+
    // matrix1を複製してmatrix2に代入
+
    matrix2 = (int[,])matrix1.Clone();
+

          
+
    // 複製元と複製後の配列の要素を変更
+
    matrix1[0, 0] = 99;
+
    matrix2[0, 0] = -1;
+

          
+
    // それぞれの配列の内容を表示
+
    for (int d1 = 0; d1 < matrix1.GetLength(0); d1++) {
+
      for (int d2 = 0; d2 < matrix1.GetLength(1); d2++) {
+
        Console.Write("{0}, ", matrix1[d1, d2]);
+
      }
+
      Console.WriteLine();
+
    }
+
    Console.WriteLine();
+

          
+
    for (int d1 = 0; d1 < matrix2.GetLength(0); d1++) {
+
      for (int d2 = 0; d2 < matrix2.GetLength(1); d2++) {
+
        Console.Write("{0}, ", matrix2[d1, d2]);
+
      }
+
      Console.WriteLine();
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,2次元配列の複製){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim matrix1 As Integer(,) = { _
+
      {0, 1, 2, 3}, _
+
      {4, 5, 6, 7}, _
+
      {8, 9, 10, 11} _
+
    }
+
    Dim matrix2 As Integer(,)
+

          
+
    ' matrix1を複製してmatrix2に代入
+
    matrix2 = DirectCast(matrix1.Clone(), Integer(,))
+

          
+
    ' 複製元と複製後の配列の要素を変更
+
    matrix1(0, 0) = 99
+
    matrix2(0, 0) = -1
+

          
+
    ' それぞれの配列の内容を表示
+
    For d1 As Integer = 0 To matrix1.GetLength(0) - 1
+
      For d2 As Integer = 0 To matrix1.GetLength(1) - 1
+
        Console.Write("{0}, ", matrix1(d1, d2))
+
      Next
+
      Console.WriteLine()
+
    Next
+
    Console.WriteLine()
+

          
+
    For d1 As Integer = 0 To matrix2.GetLength(0) - 1
+
      For d2 As Integer = 0 To matrix2.GetLength(1) - 1
+
        Console.Write("{0}, ", matrix2(d1, d2))
+
      Next
+
      Console.WriteLine()
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
99, 1, 2, 3, 
+
4, 5, 6, 7, 
+
8, 9, 10, 11, 
+

          
+
-1, 1, 2, 3, 
+
4, 5, 6, 7, 
+
8, 9, 10, 11, 
+
}}
+

          
+

          
+

          
+
**複写 (Copy, CopyTo) [#Array.Copy]
+
&msdn(netfx,member,System.Array.Copy){Array.Copyメソッド};は、Cloneメソッドとは異なり配列の内容を既に存在する別の配列に複写します。 引数で''複写する長さ(要素数)''を指定できるので、配列の途中までをコピーするということも出来ます。 当然、複写先の配列は複写元と同じがそれ以上の長さを持っている必要があります。 Array.Copyメソッドも、Array.Cloneメソッドと同様要素の''簡易コピー''を行います。
+

          
+
#tabpage(C#)
+
#code(cs,1次元配列の複写){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 複写元の配列
+
    int[] arr1 = {0, 1, 2, 3, 4};
+

          
+
    // 初期化されていない配列を確保
+
    int[] arr2 = new int[5];
+

          
+
    foreach (int elem in arr2) {
+
      Console.Write("{0}, ", elem);
+
    }
+
    Console.WriteLine();
+

          
+
    // arr1の要素の先頭から3個分をarr2に複写
+
    Array.Copy(arr1, arr2, 3);
+

          
+
    foreach (int elem in arr2) {
+
      Console.Write("{0}, ", elem);
+
    }
+
    Console.WriteLine();
+

          
+
    // arr1の全要素をarr2に複写
+
    Array.Copy(arr1, arr2, arr1.Length);
+

          
+
    foreach (int elem in arr2) {
+
      Console.Write("{0}, ", elem);
+
    }
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,1次元配列の複写){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 複写元の配列
+
    Dim arr1() As Integer = {0, 1, 2, 3, 4}
+

          
+
    ' 初期化されていない配列を確保
+
    Dim arr2(4) As Integer
+

          
+
    For Each elem As Integer In arr2
+
      Console.Write("{0}, ", elem)
+
    Next
+
    Console.WriteLine()
+

          
+
    ' arr1の要素の先頭から3個分をarr2に複写
+
    Array.Copy(arr1, arr2, 3)
+

          
+
    For Each elem As Integer In arr2
+
      Console.Write("{0}, ", elem)
+
    Next
+
    Console.WriteLine()
+

          
+
    ' arr1の全要素をarr2に複写
+
    Array.Copy(arr1, arr2, arr1.Length)
+

          
+
    For Each elem As Integer In arr2
+
      Console.Write("{0}, ", elem)
+
    Next
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
0, 0, 0, 0, 0, 
+
0, 1, 2, 0, 0, 
+
0, 1, 2, 3, 4, 
+
}}
+

          
+
複写する長さだけでなく、''複写元と複写先の始点となるインデックス''を指定して複写することも出来ます。 Arrayクラスには部分配列を抜き出すArray.Sliceのようなメソッドは用意されていませんが、次の例のように配列の生成と部分配列の複写を行うことで、Array.Slice相当の処理を行うことが出来ます。
+

          
+
#tabpage(C#)
+
#code(cs,部分配列の抽出 (slice)){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 複写元の配列
+
    int[] arr1 = {0, 1, 2, 3, 4};
+

          
+
    // 初期化されていない配列を確保
+
    int[] arr2 = new int[3];
+

          
+
    // arr1の部分配列(インデックス2から3個分)をarr2のインデックス0以降に複写
+
    Array.Copy(arr1, 2, arr2, 0, 3);
+

          
+
    foreach (int elem in arr2) {
+
      Console.Write("{0}, ", elem);
+
    }
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,部分配列の抽出 (slice)){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 複写元の配列
+
    Dim arr1() As Integer = {0, 1, 2, 3, 4}
+

          
+
    ' 初期化されていない配列を確保
+
    Dim arr2(2) As Integer
+

          
+
    ' arr1の部分配列(インデックス2から3個分)をarr2のインデックス0以降に複写
+
    Array.Copy(arr1, 2, arr2, 0, 3)
+

          
+
    For Each elem As Integer In arr2
+
      Console.Write("{0}, ", elem)
+
    Next
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
2, 3, 4, 
+
}}
+

          
+
同様に、配列の連結を行うArray.Concatのようなメソッドも用意されていませんが、次の例のように連結後の配列の生成と連結元の配列の複写を行うことで、Array.Concat相当の処理を行うことが出来ます。
+

          
+
#tabpage(C#)
+
#code(cs,配列の連結 (concat)){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 連結元の配列
+
    int[] arr1 = {0, 1, 2, 3, 4};
+
    int[] arr2 = {5, 6, 7};
+

          
+
    // 連結後の配列となる、初期化されていない配列を確保
+
    int[] arr3 = new int[arr1.Length + arr2.Length];
+

          
+
    // arr1の内容をarr3の先頭に複写
+
    Array.Copy(arr1, 0, arr3, 0, arr1.Length);
+

          
+
    // arr2の内容をarr3の続きに複写
+
    Array.Copy(arr2, 0, arr3, arr1.Length, arr2.Length);
+

          
+
    foreach (int elem in arr3) {
+
      Console.Write("{0}, ", elem);
+
    }
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,配列の連結 (concat)){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 連結元の配列
+
    Dim arr1() As Integer = {0, 1, 2, 3, 4}
+
    Dim arr2() As Integer = {5, 6, 7}
+

          
+
    ' 連結後の配列となる、初期化されていない配列を確保
+
    Dim arr3(arr1.Length + arr2.Length - 1) As Integer
+

          
+
    ' arr1の内容をarr3の先頭に複写
+
    Array.Copy(arr1, 0, arr3, 0, arr1.Length)
+

          
+
    ' arr2の内容をarr3の続きに複写
+
    Array.Copy(arr2, 0, arr3, arr1.Length, arr2.Length)
+

          
+
    For Each elem As Integer In arr3
+
      Console.Write("{0}, ", elem)
+
    Next
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
0, 1, 2, 3, 4, 5, 6, 7, 
+
}}
+

          
+
多次元配列もArray.Copyメソッドで複写できます。 多次元配列を複写する場合は、次元数が同じで複写先の長さが十分であれば、複写元と複写先で次元毎の長さが異なっていても複写することが出来ます。
+

          
+
#tabpage(C#)
+
#code(cs,2次元配列の複写){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 複写元の2次元配列(長さが4×3)
+
    int[,] matrix1 = {
+
      {0, 1, 2, 3},
+
      {4, 5, 6, 7},
+
      {8, 9, 10, 11},
+
    };
+

          
+
    // 複写先の2次元配列(長さが3×5)を確保
+
    int[,] matrix2 = new int[5, 3];
+

          
+
    // 配列を複写
+
    Array.Copy(matrix1, matrix2, matrix1.Length);
+

          
+
    // それぞれの配列の内容を表示
+
    Print(matrix1);
+

          
+
    Console.WriteLine();
+

          
+
    Print(matrix2);
+
  }
+

          
+
  static void Print(int[,] matrix)
+
  {
+
    for (int d1 = 0; d1 < matrix.GetLength(0); d1++) {
+
      for (int d2 = 0; d2 < matrix.GetLength(1); d2++) {
+
        Console.Write("{0}, ", matrix[d1, d2]);
+
      }
+
      Console.WriteLine();
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,2次元配列の複写){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 複写元の2次元配列(長さが4×3)
+
    Dim matrix1 As Integer(,) = { _
+
      {0, 1, 2, 3}, _
+
      {4, 5, 6, 7}, _
+
      {8, 9, 10, 11} _
+
    }
+

          
+
    ' 複写先の2次元配列(長さが3×5)を確保
+
    Dim matrix2(4, 2) As Integer
+

          
+
    ' 配列を複写
+
    Array.Copy(matrix1, matrix2, matrix1.Length)
+

          
+
    ' それぞれの配列の内容を表示
+
    Print(matrix1)
+

          
+
    Console.WriteLine()
+

          
+
    Print(matrix2)
+
  End Sub
+

          
+
  Shared Sub Print(ByVal matrix As Integer(,))
+
    For d1 As Integer = 0 To matrix.GetLength(0) - 1
+
      For d2 As Integer = 0 To matrix.GetLength(1) - 1
+
        Console.Write("{0}, ", matrix(d1, d2))
+
      Next
+
      Console.WriteLine()
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
0, 1, 2, 3, 
+
4, 5, 6, 7, 
+
8, 9, 10, 11, 
+

          
+
0, 1, 2, 
+
3, 4, 5, 
+
6, 7, 8, 
+
9, 10, 11, 
+
0, 0, 0, 
+
}}
+

          
+
Array.Copyメソッドの他にも、&msdn(netfx,member,System.Array.CopyTo){Array.CopyToメソッド};を使って複写することも出来ます。 このメソッドはArray.Copyとは異なりインスタンスメソッドです。 また、引数に指定するのは''複写先の始点となるインデックス''で、常に複写元の配列全体が複写されます。
+

          
+
#tabpage(C#)
+
#code(cs,CopyToメソッドを使った複写){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 複写元の配列
+
    int[] arr1 = {0, 1, 2, 3, 4};
+

          
+
    // 初期化されていない配列を確保
+
    int[] arr2 = new int[7];
+

          
+
    // arr1の全要素をarr2のインデックス1以降に複写
+
    arr1.CopyTo(arr2, 1);
+

          
+
    foreach (int elem in arr2) {
+
      Console.Write("{0}, ", elem);
+
    }
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,CopyToメソッドを使った複写){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 複写元の配列
+
    Dim arr1() As Integer = {0, 1, 2, 3, 4}
+

          
+
    ' 初期化されていない配列を確保
+
    Dim arr2(6) As Integer
+

          
+
    ' arr1の全要素をarr2のインデックス1以降に複写
+
    arr1.CopyTo(arr2, 1)
+

          
+
    For Each elem As Integer In arr2
+
      Console.Write("{0}, ", elem)
+
    Next
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
0, 0, 1, 2, 3, 4, 0, 
+
}}
+

          
+

          
+

          
+
*配列の作成・要素の取得と設定 (CreateInstance, GetValue, SetValue) [#Array.CreateInstance]
+
言語で用意されている構文を使う他に、&msdn(netfx,member,System.Array.CreateInstance){Array.CreateInstanceメソッド};を使うことで任意の型・任意の長さの配列を作成することが出来ます。 このメソッドの戻り値は&msdn(netfx,type,System.Array){Arrayクラス};となるので、必要に応じて適切な配列型にキャストしてから使います。 このメソッドで作成した配列は、通常の構文で作成した配列と何ら変わりありません。
+

          
+
また、&msdn(netfx,member,System.Array.GetValue){Array.GetValueメソッド};および&msdn(netfx,member,System.Array.SetValue){Array.SetValueメソッド};を使うことで、配列の各要素にアクセスするための構文(''インデクサ'')を使用せずに配列に値を取得・設定することが出来ます。 このメソッドは配列の型・次元がどのようなものでも値を取得・設定することが出来ます。
+

          
+
#tabpage(C#)
+
#code(cs,配列の作成・要素の取得と設定){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 型がintで長さが5の配列を作成
+
    int[] arr1 = (int[])Array.CreateInstance(typeof(int), 5);
+

          
+
    arr1[0] = 0;
+
    arr1[1] = 1;
+
    arr1[2] = 2;
+
    arr1[3] = 3;
+
    arr1[4] = 4;
+

          
+
    foreach (int elem in arr1) {
+
      Console.Write("{0}, ", elem);
+
    }
+
    Console.WriteLine();
+
    Console.WriteLine();
+

          
+
    // 型がstringで長さが3の配列を作成
+
    Array arr2 = Array.CreateInstance(typeof(string), 3);
+

          
+
    // SetValueメソッドを使って値を設定
+
    arr2.SetValue("Alice", 0);    // 配列のインデックス0に文字列"Alice"を設定
+
    arr2.SetValue("Bob", 1);      // 配列のインデックス1に文字列"Bob"を設定
+
    arr2.SetValue("Charlie", 2);  // 配列のインデックス2に文字列"Charlie"を設定
+

          
+
    // GetValueメソッドを使って値を取得
+
    for (int i = 0; i < arr2.Length; i++) {
+
      Console.WriteLine("arr2[{0}] = {1}", i, arr2.GetValue(i));
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,配列の作成・要素の取得と設定){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 型がIntegerで長さが5の配列を作成
+
    Dim arr1() As Integer = DirectCast(Array.CreateInstance(GetType(Integer), 5), Integer())
+

          
+
    arr1(0) = 0
+
    arr1(1) = 1
+
    arr1(2) = 2
+
    arr1(3) = 3
+
    arr1(4) = 4
+

          
+
    For Each elem As Integer In arr1
+
      Console.Write("{0}, ", elem)
+
    Next
+
    Console.WriteLine()
+
    Console.WriteLine()
+

          
+
    ' 型がStringで長さが3の配列を作成
+
    Dim arr2 As Array = Array.CreateInstance(GetType(String), 3)
+

          
+
    ' SetValueメソッドを使って値を設定
+
    arr2.SetValue("Alice", 0)   ' 配列のインデックス0に文字列"Alice"を設定
+
    arr2.SetValue("Bob", 1)     ' 配列のインデックス1に文字列"Bob"を設定
+
    arr2.SetValue("Charlie", 2) ' 配列のインデックス2に文字列"Charlie"を設定
+

          
+
    ' GetValueメソッドを使って値を取得
+
    For i As Integer = 0 To arr2.Length - 1
+
      Console.WriteLine("arr2({0}) = {1}", i, arr2.GetValue(i))
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
0, 1, 2, 3, 4, 
+

          
+
arr2(0) = Alice
+
arr2(1) = Bob
+
arr2(2) = Charlie
+
}}
+

          
+
Array.CreateInstance, Array.GetValue, Array.SetValueの各メソッドは、多次元配列でも使うことが出来ます。 次の例では、Array.CreateInstanceメソッドで指定された型の行列を表す2次元配列を作成し、Array.SetValueメソッドで値を設定して単位行列を構成しています。
+

          
+
#tabpage(C#)
+
#code(cs,多次元配列の作成と要素への値の設定){{
+
using System;
+

          
+
class Sample {
+
  // 任意の長さ・型の単位行列を生成する
+
  static Array CreateIdentityMatrix(int length, Type typeOfMatrix)
+
  {
+
    // 指定された型でlength×length行列となる2次元配列を作成
+
    Array matrix = Array.CreateInstance(typeOfMatrix, length, length);
+

          
+
    // 行列の対角成分に1、それ以外を0に設定する
+
    for (int i = 0; i < length; i++) {
+
      for (int j = 0; j < length; j++) {
+
        if (i == j)
+
          matrix.SetValue(1, i, j);
+
        else
+
          matrix.SetValue(0, i, j);
+
      }
+
    }
+

          
+
    return matrix;
+
  }
+

          
+
  // 行列を表示する
+
  static void PrintMatrix(Array matrix)
+
  {
+
    for (int i = 0; i < matrix.GetLength(1); i++) {
+
      Console.Write("(");
+
      for (int j = 0; j < matrix.GetLength(0); j++) {
+
        Console.Write("{0,-5} ", matrix.GetValue(i, j));
+
      }
+
      Console.WriteLine(")");
+
    }
+
  }
+

          
+
  static void Main()
+
  {
+
    // int型で2行2列の単位行列を作成
+
    int[,] matrix1 = (int[,])CreateIdentityMatrix(2, typeof(int));
+

          
+
    PrintMatrix(matrix1);
+
    Console.WriteLine();
+

          
+
    // float型で4行4列の単位行列を作成
+
    float[,] matrix2 = (float[,])CreateIdentityMatrix(4, typeof(float));
+

          
+
    // 行列内の各要素をスケーリング
+
    for (int i = 0; i < 4; i++) {
+
      for (int j = 0; j < 4; j++) {
+
        matrix2[i, j] *= 0.25f;
+
      }
+
    }
+

          
+
    PrintMatrix(matrix2);
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,多次元配列の作成と要素への値の設定){{
+
Imports System
+

          
+
Class Sample
+
  ' 任意の長さ・型の単位行列を生成する
+
  Shared Function CreateIdentityMatrix(ByVal length As Integer, ByVal typeOfMatrix As Type) As Array
+
    ' 指定された型でlength×length行列となる2次元配列を作成
+
    Dim matrix As Array = Array.CreateInstance(typeOfMatrix, length, length)
+

          
+
    ' 行列の対角成分に1、それ以外を0に設定する
+
    For i As Integer = 0 To length - 1
+
      For j As Integer = 0 To length - 1
+
        If i = j Then
+
          matrix.SetValue(1, i, j)
+
        Else
+
          matrix.SetValue(0, i, j)
+
        End If
+
      Next
+
    Next
+

          
+
    Return matrix
+
  End Function
+

          
+
  ' 行列を表示する
+
  Shared Sub PrintMatrix(ByVal matrix As Array)
+
    For i As Integer = 0 To matrix.GetLength(1) - 1
+
      Console.Write("(")
+
      For j As Integer = 0 To matrix.GetLength(0) - 1
+
        Console.Write("{0,-5} ", matrix.GetValue(i, j))
+
      Next
+
      Console.WriteLine(")")
+
    Next
+
  End Sub
+

          
+
  Shared Sub Main()
+
    ' Integer型で2行2列の単位行列を作成
+
    Dim matrix1 As Integer(,) = DirectCast(CreateIdentityMatrix(2, GetType(Integer)), Integer(,))
+

          
+
    PrintMatrix(matrix1)
+
    Console.WriteLine()
+

          
+
    ' Single型で4行4列の単位行列を作成
+
    Dim matrix2 As Single(,) = DirectCast(CreateIdentityMatrix(4, GetType(Single)), Single(,))
+

          
+
    ' 行列内の各要素をスケーリング
+
    For i As Integer = 0 To 3
+
      For j As Integer = 0 To 3
+
        matrix2(i, j) *= 0.25F
+
      Next
+
    Next
+

          
+
    PrintMatrix(matrix2)
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
(1     0     )
+
(0     1     )
+

          
+
(0.25  0     0     0     )
+
(0     0.25  0     0     )
+
(0     0     0.25  0     )
+
(0     0     0     0.25  )
+

          
+
}}
+

          
+

          
+

          
+
*読み取り専用化 (AsReadOnly) [#Array.AsReadOnly]
+
&msdn(netfx,member,System.Array.AsReadOnly){Array.AsReadOnlyメソッド};を使うことで、配列を元に読み取り専用のコレクションを作成することが出来ます。 このメソッドの戻り値は&msdn(netfx,type,System.Collections.ObjectModel.ReadOnlyCollection`1){ReadOnlyCollection};で、これは読み取り専用にした配列のように振る舞います。 例えば、インデックスを指定して要素に値を設定しようとするとコンパイルエラーとなり、IList等のインターフェイスにキャストして無理やり変更しようとしても&msdn(netfx,type,System.NotSupportedException){NotSupportedException};がスローされます。 それ以外の操作、例えば要素の参照や値の列挙は、通常の配列と同様に振る舞います。 なお、通常の配列と異なりReadOnlyCollectionにはLengthプロパティが無いので、代わりにCountプロパティを参照します。
+

          
+
#tabpage(C#)
+
#code(cs,配列の読み取り専用化){{
+
using System;
+
using System.Collections.ObjectModel;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    int[] source = {0, 1, 2, 3, 4};
+

          
+
    // 配列を読み取り専用にする
+
    ReadOnlyCollection<int> arr = Array.AsReadOnly(source);
+

          
+
    // 要素を列挙
+
    for (int i = 0; i < arr.Count; i++) {
+
      Console.Write("{0}, ", arr[i]);
+
    }
+
    Console.WriteLine();
+

          
+
    // 読み取り専用のため、要素の設定は出来ない
+
    // sample.cs(20,5): error CS0200: プロパティまたはインデクサー 'System.Collections.ObjectModel.ReadOnlyCollection<int>.this[int]' は読み取り専用なので、割り当てることはできません。
+
    //arr[1] = 5;
+

          
+
    // IListインターフェイスを経由して、無理やり要素を変更しようとする
+
    (arr as System.Collections.IList)[0] = 5;
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,配列の読み取り専用化){{
+
Imports System
+
Imports System.Collections.ObjectModel
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim source() As Integer = {0, 1, 2, 3, 4}
+

          
+
    ' 配列を読み取り専用にする
+
    Dim arr As ReadOnlyCollection(Of Integer) = Array.AsReadOnly(source)
+

          
+
    ' 要素を列挙
+
    For i As Integer = 0 To arr.Count - 1
+
      Console.Write("{0}, ", arr(i))
+
    Next
+
    Console.WriteLine()
+

          
+
    ' 読み取り専用のため、要素の設定は出来ない
+
    ' E:\sample.vb(19) : error BC30526: プロパティ 'Item' は 'ReadOnly' です。
+
    'arr(1) = 5
+

          
+
    ' IListインターフェイスを経由して、無理やり要素を変更しようとする
+
    DirectCast(arr, System.Collections.IList)(0) = 5
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
0, 1, 2, 3, 4,
+

          
+
ハンドルされていない例外: System.NotSupportedException: コレクションは読み取り専用です。
+
   場所 System.Collections.ObjectModel.ReadOnlyCollection`1.System.Collections.IList.set_Item(Int32 index, Object value)
+
   場所 Sample.Main()
+
}}
+

          
+
Array.AsReadOnlyメソッドは読み取り専用のラッパーを作成するだけであり、元となった配列が読み取り専用となるのではないため値を設定することが可能です。 元の配列を変更すると、作成したReadOnlyCollectionにもその変更が反映されます。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+
using System.Collections.ObjectModel;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    int[] source = {0, 1, 2, 3, 4};
+

          
+
    // 配列を読み取り専用にする
+
    ReadOnlyCollection<int> arr = Array.AsReadOnly(source);
+

          
+
    // 元になった配列に変更を加える
+
    source[0] = 5;
+

          
+
    // 読み取り専用コレクションの要素を列挙
+
    for (int i = 0; i < arr.Count; i++) {
+
      Console.Write("{0}, ", arr[i]);
+
    }
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+
Imports System.Collections.ObjectModel
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim source() As Integer = {0, 1, 2, 3, 4}
+

          
+
    ' 配列を読み取り専用にする
+
    Dim arr As ReadOnlyCollection(Of Integer) = Array.AsReadOnly(source)
+

          
+
    ' 元になった配列に変更を加える
+
    source(0) = 5
+

          
+
    ' 読み取り専用コレクションの要素を列挙
+
    For i As Integer = 0 To arr.Count - 1
+
      Console.Write("{0}, ", arr(i))
+
    Next
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
5, 1, 2, 3, 4, 
+
}}
+

          
+
ReadOnlyCollectionについては[[programming/netfx/collections/3_objectmodel#ReadOnlyCollection]]でも解説しています。
+

          
+

          
+

          
+
*要素の並べ替え
+
**リバース (Reverse) [#Array.Reverse]
+
&msdn(netfx,member,System.Array.Reverse){Array.Reverseメソッド};を使うことで配列内の全要素の並びを逆順に(リバース)することが出来ます。 逆順にする最初のインデックスと要素数を指定することで、配列内の一部分だけを逆順にすることも出来ます。
+

          
+
#tabpage(C#)
+
#code(cs,配列のリバース){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    int[] arr = {0, 1, 2, 3, 4};
+

          
+
    // 配列内の全要素の並びを逆順にする
+
    Array.Reverse(arr);
+

          
+
    foreach (int elem in arr) {
+
      Console.Write("{0}, ", elem);
+
    }
+
    Console.WriteLine();
+

          
+
    // 配列内のインデックス2から3個分の要素の並びを逆順にする
+
    Array.Reverse(arr, 2, 3);
+

          
+
    foreach (int elem in arr) {
+
      Console.Write("{0}, ", elem);
+
    }
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,配列のリバース){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim arr() As Integer = {0, 1, 2, 3, 4}
+

          
+
    ' 配列内の全要素の並びを逆順にする
+
    Array.Reverse(arr)
+

          
+
    For Each elem As Integer In arr
+
      Console.Write("{0}, ", elem)
+
    Next
+
    Console.WriteLine()
+

          
+
    ' 配列内のインデックス2から3個分の要素の並びを逆順にする
+
    Array.Reverse(arr, 2, 3)
+

          
+
    For Each elem As Integer In arr
+
      Console.Write("{0}, ", elem)
+
    Next
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
4, 3, 2, 1, 0, 
+
4, 3, 0, 1, 2, 
+
}}
+

          
+
ジャグ配列をリバースすることも出来ますが、その場合は1段目のみが逆順になります。 2段目以降をリバースする場合は、格納されている配列に対して個別にArray.Reverseメソッドを呼び出してリサイズする必要があります。
+

          
+
なお、Array.Reverseメソッドでは多次元配列を逆順にすることは出来ません。 Array.Reverseメソッドに多次元配列を指定すると、&msdn(netfx,type,System.RankException){RankException};がスローされます。
+

          
+
**ソート (Sort) [#Array.Sort]
+
&msdn(netfx,member,System.Array.Sort){Array.Sortメソッド};を使うことで配列内の全要素をソートして昇順に並べ替えることが出来ます。 ソートする最初のインデックスと要素数を指定することで、配列内の一部分だけをソートすることも出来ます。
+

          
+
#tabpage(C#)
+
#code(cs,配列のソート){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    int[] arr1 = {4, 2, 0, 3, 1};
+

          
+
    // 配列内の全要素を昇順に並べ替える
+
    Array.Sort(arr1);
+

          
+
    foreach (int elem in arr1) {
+
      Console.Write("{0}, ", elem);
+
    }
+
    Console.WriteLine();
+

          
+
    int[] arr2 = {4, 3, 2, 1, 0};
+

          
+
    // 配列内のインデックス2から3個分の要素を昇順に並べ替える
+
    Array.Sort(arr2, 2, 3);
+

          
+
    foreach (int elem in arr2) {
+
      Console.Write("{0}, ", elem);
+
    }
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,配列のソート){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim arr1() As Integer = {4, 2, 0, 3, 1}
+

          
+
    ' 配列内の全要素を昇順に並べ替える
+
    Array.Sort(arr1)
+

          
+
    For Each elem As Integer In arr1
+
      Console.Write("{0}, ", elem)
+
    Next
+
    Console.WriteLine()
+

          
+
    Dim arr2() As Integer = {4, 3, 2, 1, 0}
+

          
+
    ' 配列内のインデックス2から3個分の要素を昇順に並べ替える
+
    Array.Sort(arr2, 2, 3)
+

          
+
    For Each elem As Integer In arr2
+
      Console.Write("{0}, ", elem)
+
    Next
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
0, 1, 2, 3, 4, 
+
4, 3, 0, 1, 2, 
+
}}
+

          
+
Array.Sortメソッドを使ったソートについてより詳しくは[[programming/netfx/sorting/0_basictypes]]で解説しています。 また、Array.Sortメソッドを使って多次元配列やジャグ配列をソートする方法については[[programming/netfx/sorting/2_arrays]]で詳しく解説しています。
+

          
+

          
+

          
+
*要素の検索
+
ここでは配列内にある要素の検索を行うメソッドについて紹介します。 なお、配列の型によっては引数でIComparerなどのインターフェイスが必要になりますが、ここではそういった事項に付いては触れません。 必要に応じて[[programming/netfx/comparison/0_comparison]]や[[programming/netfx/comparison/1_equation]]を参照してください。
+

          
+
**要素の位置の検索 (IndexOf, LastIndexOf, BinarySearch) [#Array.IndexOf]
+
&msdn(netfx,member,System.Array.IndexOf){Array.IndexOfメソッド};を使うことで配列内における指定した値を持つ要素の位置を検索して取得することが出来ます。 このメソッドは配列の前方から検索を行うため、配列内に同一の値を持つ要素がある場合は、そのうちより小さい(最初に見つかった)インデックスを返します。 逆に、&msdn(netfx,member,System.Array.LastIndexOf){Array.LastIndexOfメソッド};は配列の後方から検索を行うため、より大きい(前方から見て最後に見つかった)インデックスを返します。 どちらのメソッドも、配列内に該当する要素が無い場合は-1が返されます。
+

          
+
#tabpage(C#)
+
#code(cs,要素の位置の検索){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    int[] arr = {0, 1, 0, 2, 0, 3};
+

          
+
    // 値に0が格納されている最初のインデックスを取得
+
    Console.WriteLine("IndexOf(0) = {0}", Array.IndexOf(arr, 0));
+

          
+
    // 値に0が格納されている最後のインデックスを取得
+
    Console.WriteLine("LastIndexOf(0) = {0}", Array.LastIndexOf(arr, 0));
+

          
+
    // 値に4が格納されている最初のインデックスを取得
+
    Console.WriteLine("IndexOf(4) = {0}", Array.IndexOf(arr, 4));
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,要素の位置の検索){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim arr() As Integer = {0, 1, 0, 2, 0, 3}
+

          
+
    ' 値に0が格納されている最初のインデックスを取得
+
    Console.WriteLine("IndexOf(0) = {0}", Array.IndexOf(arr, 0))
+

          
+
    ' 値に0が格納されている最後のインデックスを取得
+
    Console.WriteLine("LastIndexOf(0) = {0}", Array.LastIndexOf(arr, 0))
+

          
+
    ' 値に4が格納されている最初のインデックスを取得
+
    Console.WriteLine("IndexOf(4) = {0}", Array.IndexOf(arr, 4))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
IndexOf(0) = 0
+
LastIndexOf(0) = 4
+
IndexOf(4) = -1
+
}}
+

          
+
&msdn(netfx,member,System.Array.BinarySearch){Array.BinarySearchメソッド};を使うことでも配列内における要素の位置を検索出来ます。 Array.IndexOfメソッドは先頭から順に1つずつ要素を検証していくのに対し、Array.BinarySearchメソッドは二分探索によって要素を検索するため、より高速に要素の位置を検索できます(要素数nの配列ではIndexOfがO(n)であるのに対し、BinarySearchはO(log&sub{2};n)となる)。 ただし、いくつかの点でArray.IndexOfメソッドとは異なるため、単純にArray.IndexOfメソッドの代わりとしてArray.BinarySearchメソッドを適用できるとは限りません。
+

          
+
まず、Array.BinarySearchメソッドを使って要素の位置を検索する場合、''配列の要素が昇順に並んでいる必要があります''。 そのため、Array.BinarySearchメソッドを使う場合は、あらかじめ昇順に並んでいる配列に対して使うか、呼び出す前にあらかじめ配列をソートしておくようにします。 昇順に並んでいない配列に対してArray.BinarySearchメソッドを使っても例外がスローされることはありませんが、正しい結果は得られません。
+

          
+
次に、Array.BinarySearchメソッドは該当する要素が見つかった場合はそのインデックスを返しますが、Array.IndexOfメソッドとは異なり、該当する要素が複数ある場合でもそのうちもっとも小さいインデックスが返されるとは限りません。 また、配列内に該当する要素が無い場合は負の数が返されます(-1が返されるとは限りません)。
+

          
+
#tabpage(C#)
+
#code(cs,二分探索による要素の位置の検索){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 要素が昇順に並んでいる配列
+
    int[] arr = {0, 1, 1, 2, 2, 2, 3, 4, 4, 4, 4, 5};
+

          
+
    // IndexOfメソッドで値に2が格納されているインデックスを取得
+
    Console.WriteLine("IndexOf(2) = {0}", Array.IndexOf(arr, 2));
+

          
+
    // BinarySearchメソッドで値に2が格納されているインデックスを取得
+
    Console.WriteLine("BinarySearch(2) = {0}", Array.BinarySearch(arr, 2));
+

          
+
    // 値に7が格納されているインデックスを取得
+
    Console.WriteLine("IndexOf(7) = {0}", Array.IndexOf(arr, 7));
+
    Console.WriteLine("BinarySearch(7) = {0}", Array.BinarySearch(arr, 7));
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,二分探索による要素の位置の検索){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 要素が昇順に並んでいる配列
+
    Dim arr() As Integer = {0, 1, 1, 2, 2, 2, 3, 4, 4, 4, 4, 5}
+

          
+
    ' IndexOfメソッドで値に2が格納されているインデックスを取得
+
    Console.WriteLine("IndexOf(2) = {0}", Array.IndexOf(arr, 2))
+

          
+
    ' BinarySearchメソッドで値に2が格納されているインデックスを取得
+
    Console.WriteLine("BinarySearch(2) = {0}", Array.BinarySearch(arr, 2))
+

          
+
    ' 値に7が格納されているインデックスを取得
+
    Console.WriteLine("IndexOf(7) = {0}", Array.IndexOf(arr, 7))
+
    Console.WriteLine("BinarySearch(7) = {0}", Array.BinarySearch(arr, 7))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
IndexOf(2) = 3
+
BinarySearch(2) = 5
+
IndexOf(7) = -1
+
BinarySearch(7) = -13
+
}}
+

          
+
***IndexOfとBinarySearchの速度比較
+
参考までに、Array.IndexOfメソッドとArray.BinarySearchメソッドを使った場合の速度の違いを比較した結果を紹介します。 次のように、IndexOfメソッドを使った検索では配列の要素数が増えるにつれ多大な時間がかかるようになっていますが、BinarySearchメソッドを使った検索では配列の要素数が増えても比較的短い時間で結果が得られています。
+

          
+
#prompt(要素数が100の場合){{
+
Length = 100
+
IndexOf:      00:00:00.0001335
+
BinarySearch: 00:00:00.0003081
+
IndexOf:      00:00:00.0000226
+
BinarySearch: 00:00:00.0000201
+
IndexOf:      00:00:00.0000257
+
BinarySearch: 00:00:00.0000195
+
}}
+

          
+
#prompt(要素数が10000の場合){{
+
Length = 10000
+
IndexOf:      00:00:00.1274312
+
BinarySearch: 00:00:00.0033034
+
IndexOf:      00:00:00.1212156
+
BinarySearch: 00:00:00.0018985
+
IndexOf:      00:00:00.1183027
+
BinarySearch: 00:00:00.0019239
+
}}
+

          
+
#prompt(要素数が100000の場合){{
+
Length = 100000
+
IndexOf:      00:00:12.8952917
+
BinarySearch: 00:00:00.0278454
+
IndexOf:      00:00:12.9067753
+
BinarySearch: 00:00:00.0270422
+
IndexOf:      00:00:13.0714185
+
BinarySearch: 00:00:00.0276836
+
}}
+

          
+
#code(cs,検証に使ったコード){{
+
using System;
+
using System.Diagnostics;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // ソート済みの要素を含む配列を作成
+
    var arr = new int[100 * 1000];
+

          
+
    for (var i = 0; i < arr.Length; i++) {
+
      arr[i] = i;
+
    }
+

          
+
    Console.WriteLine("Length = {0}", arr.Length);
+

          
+
    // 3回試行
+
    for (var c = 0; c < 3; c++) {
+
      var tick = Environment.TickCount;
+

          
+
      // IndexOfメソッドでの探索
+
      var rand1 = new Random(tick);
+
      var sw1 = Stopwatch.StartNew();
+

          
+
      for (var n = 0; n < arr.Length; n++) {
+
        Array.IndexOf(arr, rand1.Next(0, arr.Length));
+
      }
+

          
+
      sw1.Stop();
+

          
+
      Console.WriteLine("IndexOf:      {0}", sw1.Elapsed);
+

          
+
      // BinarySearchメソッドでの探索
+
      var rand2 = new Random(tick);
+
      var sw2 = Stopwatch.StartNew();
+

          
+
      for (var n = 0; n < arr.Length; n++) {
+
        Array.BinarySearch(arr, rand2.Next(0, arr.Length));
+
      }
+

          
+
      sw2.Stop();
+

          
+
      Console.WriteLine("BinarySearch: {0}", sw2.Elapsed);
+
    }
+
  }
+
}
+
}}
+

          
+

          
+

          
+
**述語を使った検索 (Find, Exists, etc.) [#Array.Find]
+
Arrayクラスには、''述語''(Predicate)を使った要素の検索や取得を行うメソッドがいくつか用意されています。 条件を記述して[[デリゲート>programming/netfx/delegate/0_abstract]]の形式でこれらのメソッドに渡すことで、その条件に見合う要素を検索・取得することが出来ます。 これらのメソッドを使うことで、for文・foreach文で列挙してif文で各要素を条件と照らし合わせて検索するといった処理を、メソッドを呼び出すだけで済ませる事が出来るようになります。
+

          
+
Arrayクラスには、述語を使った要素の検索・取得を行うことが出来るメソッドとして次のようなものが用意されています。
+

          
+
|~メソッド|~機能|h
+
|&msdn(netfx,member,System.Array.Find){Find};|述語で定義された条件と一致する''最初の要素を取得''する|
+
|&msdn(netfx,member,System.Array.FindLast){FindLast};|述語で定義された条件と一致する''最後の要素を取得''する|
+
|&msdn(netfx,member,System.Array.FindAll){FindAll};|述語で定義された条件と一致する''すべての要素を取得''する|
+
|&msdn(netfx,member,System.Array.FindIndex){FindIndex};|述語で定義された条件と一致する''最初の要素のインデックスを取得''する|
+
|&msdn(netfx,member,System.Array.FindLastIndex){FindLastIndex};|述語で定義された条件と一致する''最後の要素のインデックスを取得''する|
+
|&msdn(netfx,member,System.Array.Exists){Exists};|述語で定義された条件と一致する''要素があるかどうかを判断''する|
+
|&msdn(netfx,member,System.Array.TrueForAll){TrueForAll};|述語で定義された条件と''すべての要素が合致するかどうかを判断''する|
+

          
+
次の例では、値が偶数かどうかを返すメソッドを作成し、それを述語として使用することで配列内にある偶数の要素を検索・取得しています。
+

          
+
#tabpage(C#)
+
#code(cs,述語を使った検索){{
+
using System;
+

          
+
class Sample {
+
  // 引数で与えられた数が偶数かどうか
+
  static bool IsEven(int val)
+
  {
+
    if (val % 2 == 0)
+
      return true;
+
    else
+
      return false;
+
  }
+

          
+
  static void Main()
+
  {
+
    int[] arr = {1, 4, 3, 5, 2, 6};
+

          
+
    // 「値が偶数かどうか」という述語となるデリゲート
+
    Predicate<int> isEven = IsEven;
+

          
+
    // 値が偶数の要素とそのインデックスを取得
+
    Console.WriteLine("Find: {0}", Array.Find(arr, isEven));
+
    Console.WriteLine("FindIndex: {0}", Array.FindIndex(arr, isEven));
+
    Console.WriteLine("FindLast: {0}", Array.FindLast(arr, isEven));
+
    Console.WriteLine("FindLastIndex: {0}", Array.FindLastIndex(arr, isEven));
+

          
+
    // 値が偶数の要素をすべて取得
+
    Console.Write("FindAll: ");
+

          
+
    foreach (int elem in Array.FindAll(arr, isEven)) {
+
      Console.Write("{0}, ", elem);
+
    }
+

          
+
    Console.WriteLine();
+

          
+
    // 値が偶数の要素が存在するかどうか
+
    Console.WriteLine("Exists? {0}", Array.Exists(arr, isEven));
+

          
+
    // すべての要素の値が偶数かどうか
+
    Console.WriteLine("TrueForAll? {0}", Array.TrueForAll(arr, isEven));
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,述語を使った検索){{
+
Imports System
+

          
+
Class Sample
+
  ' 引数で与えられた数が偶数かどうか
+
  Shared Function IsNumberEven(ByVal val As Integer) As Boolean
+
    If val Mod 2 = 0 Then
+
      Return True
+
    Else
+
      Return False
+
    End If
+
  End Function
+

          
+
  Shared Sub Main()
+
    Dim arr() As Integer = {1, 4, 3, 5, 2, 6}
+

          
+
    ' 「値が偶数かどうか」という述語となるデリゲート
+
    Dim isEven As Predicate(Of Integer) = AddressOf IsNumberEven
+

          
+
    ' 値が偶数の要素とそのインデックスを取得
+
    Console.WriteLine("Find: {0}", Array.Find(arr, isEven))
+
    Console.WriteLine("FindIndex: {0}", Array.FindIndex(arr, isEven))
+
    Console.WriteLine("FindLast: {0}", Array.FindLast(arr, isEven))
+
    Console.WriteLine("FindLastIndex: {0}", Array.FindLastIndex(arr, isEven))
+

          
+
    ' 値が偶数の要素をすべて取得
+
    Console.Write("FindAll: ")
+

          
+
    For Each elem As Integer In Array.FindAll(arr, isEven)
+
      Console.Write("{0}, ", elem)
+
    Next
+

          
+
    Console.WriteLine()
+

          
+
    ' 値が偶数の要素が存在するかどうか
+
    Console.WriteLine("Exists? {0}", Array.Exists(arr, isEven))
+

          
+
    ' すべての要素の値が偶数かどうか
+
    Console.WriteLine("TrueForAll? {0}", Array.TrueForAll(arr, isEven))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
Find: 4
+
FindIndex: 1
+
FindLast: 6
+
FindLastIndex: 5
+
FindAll: 4, 2, 6, 
+
Exists? True
+
TrueForAll? False
+
}}
+

          
+

          
+

          
+
*全要素の変換 (ConvertAll) [#Array.ConvertAll]
+
&msdn(netfx,member,System.Array.ConvertAll){Array.ConvertAllメソッド};を使うことで、配列内の全要素の値を変換することが出来ます。 このメソッドでは、変換処理を記述したメソッドを&msdn(netfx,type,System.Converter`2){Converterデリゲート};の形式で指定することで、その処理を配列内の全要素に適用し、その結果を格納した配列を取得することが出来ます。 このメソッドを使うことで、ある配列を別の型の配列に変換する事も出来ます。
+

          
+
#tabpage(C#)
+
#code(cs,配列内の全要素の変換){{
+
using System;
+

          
+
class Sample {
+
  // 度数を弧度に変える
+
  static double ToRadian(double degree)
+
  {
+
    return degree * Math.PI / 180.0;
+
  }
+

          
+
  static void Main()
+
  {
+
    double[] degrees = {0.0, 90.0, 180.0, 270.0};
+

          
+
    // 配列内の値をすべて弧度に変換する
+
    double[] radians = Array.ConvertAll(degrees, ToRadian);
+

          
+
    foreach (double rad in radians) {
+
      Console.Write("{0}, ", rad);
+
    }
+
    Console.WriteLine();
+

          
+
    // 配列を文字列の配列に変換して連結する
+
    Console.WriteLine(string.Join(", ", Array.ConvertAll(degrees, Convert.ToString)));
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,配列内の全要素の変換){{
+
Imports System
+

          
+
Class Sample
+
  ' 度数を弧度に変える
+
  Shared Function ToRadian(ByVal degree As Double) As Double
+
    Return degree * Math.PI / 180.0
+
  End Function
+

          
+
  Shared Sub Main()
+
    Dim degrees() As Double = {0.0, 90.0, 180.0, 270.0}
+

          
+
    ' 配列内の値をすべて弧度に変換する
+
    Dim radians() As Double = Array.ConvertAll(degrees, AddressOf ToRadian)
+

          
+
    For Each rad As Double In radians
+
      Console.Write("{0}, ", rad)
+
    Next
+
    Console.WriteLine()
+

          
+
    ' 配列を文字列の配列に変換して連結する
+
    Console.WriteLine(String.Join(", ", Array.ConvertAll(degrees, AddressOf Convert.ToString)))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
0, 1.5707963267949, 3.14159265358979, 4.71238898038469, 
+
0, 90, 180, 270
+
}}
+

          
+

          
+

          
+
*要素の列挙 (ForEach) [#Array.ForEach]
+
&msdn(netfx,member,System.Array.ForEach){Array.ForEachメソッド};を使うと、配列の要素を列挙してすべての要素に対して同一の処理を施すことが出来ます。 このメソッドでは、処理を記述したメソッドを&msdn(netfx,type,System.Action`1){Actionデリゲート};の形式で指定することで、配列内の個々の要素を引数としてそのメソッドが呼び出されます。 foreach文の内側でメソッド呼び出しを行う代わりに、このメソッドを使ってより簡単に記述することが出来ます。
+

          
+
#tabpage(C#)
+
#code(cs,配列内の全要素の列挙){{
+
using System;
+

          
+
class Sample {
+
  // 引数の値をゼロ埋めして表示
+
  static void Print(int val)
+
  {
+
    Console.WriteLine("{0:D3}", val);
+
  }
+

          
+
  static void Main()
+
  {
+
    int[] arr = {0, 1, 2, 3, 4};
+

          
+
    // 配列内の値をゼロ埋めして表示
+
    Array.ForEach(arr, Print);
+

          
+
    Console.WriteLine();
+

          
+
    // 上記の処理をforeach文で記述した場合
+
    foreach (int elem in arr) {
+
      Print(elem);
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,配列内の全要素の列挙){{
+
Imports System
+

          
+
Class Sample
+
  ' 引数の値をゼロ埋めして表示
+
  Shared Sub Print(ByVal val As Integer)
+
    Console.WriteLine("{0:D3}", val)
+
  End Sub
+

          
+
  Shared Sub Main()
+
    Dim arr() As Integer = {0, 1, 2, 3, 4}
+

          
+
    ' 配列内の値をゼロ埋めして表示
+
    Array.ForEach(arr, AddressOf Print)
+

          
+
    Console.WriteLine()
+

          
+
    ' 上記の処理をFor Eachステートメントで記述した場合
+
    For Each elem As Integer In arr
+
      Print(elem)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
000
+
001
+
002
+
003
+
004
+

          
+
000
+
001
+
002
+
003
+
004
+
}}
+

          
+
このメソッドは配列内の各要素を列挙するだけであるため、元の配列に変更を加えるような処理を行うことは出来ません。 そういった処理を行いたい場合はfor文や[[Array.ConvertAllメソッド>#Array.ConvertAll]]を使います。
+

          
+

          
+

          
+
#navi(..)
+

          

programming/netfx/arrays/index.wiki.txt

current previous
1,10 0,0
+
${smdncms:title,配列}
+
${smdncms:keywords,配列,Array}
+

          
+
ここでは配列とその宣言・作成方法・基本操作について解説します。 また、多次元配列・ジャグ配列およびすべての配列の基本クラスである&msdn(netfx,type,System.Array){Arrayクラス};についても解説します。
+

          
+
#googleadunit(banner)
+

          
+
-ページ一覧
+
#ls2_1(noroot,pathsort)
+

          

programming/netfx/arrays/1_multidimensional/index.wiki.txt

current previous
1,1623 0,0
+
${smdncms:title,多次元配列・ジャグ配列}
+
${smdncms:keywords,ジャグ配列,多段配列,配列の配列,多次元配列,矩形配列,2次元配列,3次元配列,マトリックス,行列,Rank,GetLength}
+
${smdncms:document_versions,codelang=cs,codelang=vb}
+

          
+
#navi(..)
+

          
+
.NET Frameworkでは単純な配列(1次元配列)だけでなく、2次元以上の多次元配列も扱うことが出来ます。 また、矩形の構造を持った多次元配列に加え、ジャグ配列と呼ばれる配列が入れ子になった構造の配列も扱うことが出来ます。
+

          
+
-関連するページ
+
--[[programming/netfx/sorting]]
+
---[[programming/netfx/sorting/2_arrays]]
+
--[[programming/netfx/comparison]]
+
---[[programming/netfx/comparison/2_structural]]
+

          
+
#googleadunit(banner)
+

          
+

          
+
*多次元配列とジャグ配列
+
''多次元配列''は通常の配列(1次元配列)の次元を拡張したもので、マトリックスやグリッドの様な矩形の構造を持ったデータ構造であることから、''矩形配列''とも呼ばれます。 一方''ジャグ配列''は、配列を格納することが出来る配列(配列の配列)であり、その事から''多段配列''とも呼ばれます。
+

          
+
ジャグ配列は多次元配列とは異なり、異なる要素数の配列を格納することが出来ます。 例えば、2次元配列が持ちうる要素数は1次元目の長さが&var{n};、2次元目の長さが&var{m};個とすると計&var{n};×&var{m};個となり、常に次元ごとの長さの積が全要素数となりますが、2段のジャグ配列では&var{a};個の配列+&var{b};個の配列+&var{c};個の配列…とジャグ配列内に格納されている配列の要素数の和となります。 ジャグ配列は、矩形である多次元配列とは異なり構造がギザギザ(jagged)になることが、その名前の由来となっています。
+

          
+
例として2次元配列と2段のジャグ配列を図式化すると次のようになります。 比較のために通常の配列(1次元配列)も併記します。 それぞれ4行×5列の2次元配列と1段目が4個の2段のジャグ配列で、1次元目・1段目を縦方向、2次元目・2段目を横方向で表しています。
+

          
+
#column
+
1次元配列のイメージ
+
|(0)|
+
|(1)|
+
|(2)|
+
|(3)|
+
#column
+
2次元配列のイメージ
+
|(0, 0)|(0, 1)|(0, 2)|(0, 3)|(0, 4)|
+
|(1, 0)|(1, 1)|(1, 2)|(1, 3)|(1, 4)|
+
|(2, 0)|(2, 1)|(2, 2)|(2, 3)|(2, 4)|
+
|(3, 0)|(3, 1)|(3, 2)|(3, 3)|(3, 4)|
+
#column
+
2段のジャグ配列のイメージ
+
|&column(delim=/){(0, 0)/(0, 1)};|
+
|&column(delim=/){(1, 0)/(1, 1)/(1, 2)/(1, 3)/(1, 4)};|
+
|&column(delim=/){(2, 0)/(2, 1)/(2, 2)};|
+
|&column(delim=/){(3, 0)/(3, 1)/(3, 2)/(3, 3)};|
+
#column-end
+

          
+
多次元配列は行列の演算や表計算のセル表現のなどの用途で良く使われますが、ジャグ配列の用途がイメージしづらければ、カレンダーを想像するとよいでしょう。 カレンダーでは月ごとに日数が異なりますが、これを表現するのにジャグ配列が使えます。 全12ヶ月をジャグ配列の1段目、各月の日数に応じたデータをジャグ配列の2段目で表現出来ます。
+

          
+
|*2段のジャグ配列で表現したカレンダー
+
|1月 &column{1月1日,1月2日,…,…,1月28日,1月29日,1月30日,1月31日};|
+
|2月 &column{2月1日,2月2日,…,…,2月28日};|
+
|3月 &column{3月1日,3月2日,…,…,3月28日,3月29日,3月30日,3月31日};|
+
|4月 &column{4月1日,4月2日,…,…,4月28日,4月29日,4月30日};|
+
|5月 &column{5月1日,5月2日,…,…,5月28日,5月29日,5月30日,5月31日};|
+
|CENTER:&#x3a;|
+
|CENTER:&#x3a;|
+

          
+

          
+

          
+
*多次元配列 (矩形配列)
+
**宣言・作成・要素の参照
+
早速、2次元配列を宣言・作成し要素を参照する例について見てみます。 次の例では1次元目の長さが3、2次元目の長さが4の計3×4個の要素を持つ2次元配列を作成しています。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 3×4個の要素を持つ2次元配列を作成
+
    int[,] matrix = new int[3, 4];
+

          
+
    // 1次元目のインデックスが0、2次元目のインデックスが0の要素(最初の要素)に値を設定
+
    matrix[0, 0] = 0;
+

          
+
    // 1次元目のインデックスが2、2次元目のインデックスが3の要素(最後の要素)に値を設定
+
    matrix[2, 3] = 11;
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 3×4個の要素を持つ2次元配列を作成
+
    Dim matrix(2, 3) As Integer
+

          
+
    ' 1次元目のインデックスが0、2次元目のインデックスが0の要素(最初の要素)に値を設定
+
    matrix(0, 0) = 0
+

          
+
    ' 1次元目のインデックスが2、2次元目のインデックスが3の要素(最後の要素)に値を設定
+
    matrix(2, 3) = 11
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
2次元配列を宣言する場合は、次元毎に要素数(またはインデックスの最大値)をカンマで区切って記述します。 2次元配列内の各要素を参照する場合も同様にインデックスをカンマで区切って記述します。 上記のコードで作成される2次元配列を図式化すると次のようになります。 1次元目を縦方向、2次元目を横方向で表しています。
+

          
+
|*長さが3×4の2次元配列のイメージ
+
|matrix[0, 0]|matrix[0, 1]|matrix[0, 2]|matrix[0, 3]|
+
|matrix[1, 0]|matrix[1, 1]|matrix[1, 2]|matrix[1, 3]|
+
|matrix[2, 0]|matrix[2, 1]|matrix[2, 2]|matrix[2, 3]|
+

          
+
3次元以上の配列を宣言・作成する場合も同様に、&var{1次元目};, &var{2次元目};, &var{3次元目};, … と次元の数だけカンマで区切って長さを指定します。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 4×2×3個の要素を持つ3次元配列
+
    int[,,] cube = new int[4, 2, 3];
+

          
+
    cube[0, 1, 2] = 5;
+

          
+
    // 2×2×2×2個の要素を持つ4次元配列を作成
+
    int[,,,] tesseract = new int[2, 2, 2, 2];
+

          
+
    tesseract[1, 1, 0, 1] = 16;
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 4×2×3個の要素を持つ3次元配列を作成
+
    Dim cube(3, 1, 2) As Integer
+

          
+
    cube(0, 1, 2) = 5
+

          
+
    ' 2×2×2×2個の要素を持つ4次元配列を作成
+
    Dim tesseract(1, 1, 1, 1) As Integer
+

          
+
    tesseract(1, 1, 0, 1) = 16
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
宣言されているものと異なる次元の配列を代入しようとするとコンパイル時にエラーとなります。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 3次元配列
+
    int[,,] cube = new int[4, 2, 3];
+

          
+
    // 2次元配列を格納する変数
+
    int[,] matrix;
+

          
+
    // sample.cs(13,14): error CS0029: 型 'int[*,*,*]' を型 'int[*,*]' に暗黙的に変換できません。
+
    matrix = cube;
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 3次元配列
+
    Dim cube(3, 1, 2) As Integer
+

          
+
    ' 2次元配列を格納する変数
+
    Dim matrix(,) As Integer
+

          
+
    ' E:\sample.vb(12) : error BC30414: 配列型の次元数が異なるため、型 'Integer の 3次元配列' の値を 'Integer の 2 次元配列' に変換できません。
+
    matrix = cube
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+

          
+

          
+
**初期化
+
多次元配列の場合でも配列初期化子を使って初期化することが出来ます。 配列初期化子を使って初期化する場合は、1つの次元を数列とみなして1次元配列と同様の記述で表現し、それらを入れ子にすることで複数の次元を表現します。 次の例では先ほどと同様の、1次元目の長さが3、2次元目の長さが4の計3×4個の要素を持つ2次元配列を作成すると同時に初期化を行っています。
+

          
+
#tabpage(C#)
+
#code(cs,2次元配列の初期化){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 3×4個の要素を持つ2次元配列を作成
+
    int[,] matrix = {
+
      {0, 1, 2, 3},
+
      {4, 5, 6, 7},
+
      {8, 9, 10, 11},
+
    };
+

          
+
    Console.WriteLine("matrix[0, 0] = {0}", matrix[0, 0]);
+
    Console.WriteLine("matrix[0, 1] = {0}", matrix[0, 1]);
+
    Console.WriteLine("matrix[1, 0] = {0}", matrix[1, 0]);
+
    Console.WriteLine("matrix[2, 3] = {0}", matrix[2, 3]);
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,2次元配列の初期化){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 3×4個の要素を持つ2次元配列を作成
+
    Dim matrix As Integer(,) = { _
+
      {0, 1, 2, 3}, _
+
      {4, 5, 6, 7}, _
+
      {8, 9, 10, 11} _
+
    }
+

          
+
    Console.WriteLine("matrix(0, 0) = {0}", matrix(0, 0))
+
    Console.WriteLine("matrix(0, 1) = {0}", matrix(0, 1))
+
    Console.WriteLine("matrix(1, 0) = {0}", matrix(1, 0))
+
    Console.WriteLine("matrix(2, 3) = {0}", matrix(2, 3))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
matrix[0, 0] = 0
+
matrix[0, 1] = 1
+
matrix[1, 0] = 4
+
matrix[2, 3] = 11
+
}}
+

          
+
このコードで作成・初期化される2次元配列を図式化すると次のようになります。
+

          
+
|*初期化後に2次元配列へ格納される値のイメージ
+
|~matrix[m, n]|~[m, 0]|~[m, 1]|~[m, 2]|~[m, 3]|
+
|~[0, n]|0|1|2|3|
+
|~[1, n]|4|5|6|7|
+
|~[2, n]|8|9|10|11|
+

          
+
3次元以上の多次元配列も同様にして初期化することが出来ます。 2次元目は入れ子の2段目、3次元目は入れ子の3段目と、より高い次元の数列を入れ子の内側に記述します。 次元が高くなる分、記述も複雑になるので注意してください。
+

          
+
#tabpage(C#)
+
#code(cs,3次元配列の初期化){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 4×2×3個の要素を持つ3次元配列
+
    int[,,] cube = {
+
      {  { 0,  1,  2},  { 3,  4,  5}  },
+
      {  { 6,  7,  8},  { 9, 10, 11}  },
+
      {  {12, 13, 14},  {15, 16, 17}  },
+
      {  {18, 19, 20},  {21, 22, 23}  },
+
    };
+

          
+
    Console.WriteLine("cube[0, 0, 0] = {0}", cube[0, 0, 0]);
+
    Console.WriteLine("cube[0, 0, 1] = {0}", cube[0, 0, 1]);
+
    Console.WriteLine("cube[0, 1, 0] = {0}", cube[0, 1, 0]);
+
    Console.WriteLine("cube[1, 0, 0] = {0}", cube[1, 0, 0]);
+
    Console.WriteLine("cube[3, 1, 2] = {0}", cube[3, 1, 2]);
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,3次元配列の初期化){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 4×2×3個の要素を持つ3次元配列
+
    Dim cube As Integer(,,) = { _
+
      {  { 0,  1,  2},  { 3,  4,  5}  }, _
+
      {  { 6,  7,  8},  { 9, 10, 11}  }, _
+
      {  {12, 13, 14},  {15, 16, 17}  }, _
+
      {  {18, 19, 20},  {21, 22, 23}  } _
+
    }
+

          
+
    Console.WriteLine("cube(0, 0, 0) = {0}", cube(0, 0, 0))
+
    Console.WriteLine("cube(0, 0, 1) = {0}", cube(0, 0, 1))
+
    Console.WriteLine("cube(0, 1, 0) = {0}", cube(0, 1, 0))
+
    Console.WriteLine("cube(1, 0, 0) = {0}", cube(1, 0, 0))
+
    Console.WriteLine("cube(3, 1, 2) = {0}", cube(3, 1, 2))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
cube[0, 0, 0] = 0
+
cube[0, 0, 1] = 1
+
cube[0, 1, 0] = 3
+
cube[1, 0, 0] = 6
+
cube[3, 1, 2] = 23
+
}}
+

          
+
#tabpage(C#)
+
#code(cs,4次元配列の初期化){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 2×2×2×2個の要素を持つ4次元配列
+
    int[,,,] tesseract = {
+
      {  {  {0, 1},  { 2,  3}  },  {  { 4,  5},  { 6,  7}  }  },
+
      {  {  {8, 9},  {10, 11}  },  {  {12, 13},  {14, 15}  }  },
+
    };
+

          
+
    Console.WriteLine("tesseract[0, 0, 0, 0] = {0}", tesseract[0, 0, 0, 0]);
+
    Console.WriteLine("tesseract[0, 0, 0, 1] = {0}", tesseract[0, 0, 0, 1]);
+
    Console.WriteLine("tesseract[0, 0, 1, 0] = {0}", tesseract[0, 0, 1, 0]);
+
    Console.WriteLine("tesseract[0, 1, 0, 0] = {0}", tesseract[0, 1, 0, 0]);
+
    Console.WriteLine("tesseract[1, 0, 0, 0] = {0}", tesseract[1, 0, 0, 0]);
+
    Console.WriteLine("tesseract[1, 1, 1, 1] = {0}", tesseract[1, 1, 1, 1]);
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,4次元配列の初期化){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 2×2×2×2個の要素を持つ4次元配列
+
    Dim tesseract As Integer(,,,) = { _
+
      {  {  {0, 1},  { 2,  3}  },  {  { 4,  5},  { 6,  7}  }  }, _
+
      {  {  {8, 9},  {10, 11}  },  {  {12, 13},  {14, 15}  }  } _
+
    }
+

          
+
    Console.WriteLine("tesseract(0, 0, 0, 0) = {0}", tesseract(0, 0, 0, 0))
+
    Console.WriteLine("tesseract(0, 0, 0, 1) = {0}", tesseract(0, 0, 0, 1))
+
    Console.WriteLine("tesseract(0, 0, 1, 0) = {0}", tesseract(0, 0, 1, 0))
+
    Console.WriteLine("tesseract(0, 1, 0, 0) = {0}", tesseract(0, 1, 0, 0))
+
    Console.WriteLine("tesseract(1, 0, 0, 0) = {0}", tesseract(1, 0, 0, 0))
+
    Console.WriteLine("tesseract(1, 1, 1, 1) = {0}", tesseract(1, 1, 1, 1))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
tesseract[0, 0, 0, 0] = 0
+
tesseract[0, 0, 0, 1] = 1
+
tesseract[0, 0, 1, 0] = 2
+
tesseract[0, 1, 0, 0] = 4
+
tesseract[1, 0, 0, 0] = 8
+
tesseract[1, 1, 1, 1] = 15
+
}}
+

          
+

          
+

          
+
**長さ・次元数の取得
+
多次元配列でもLengthプロパティを参照することが出来ますが、返される値は多次元配列の''全要素数''となります。 次元毎の長さを取得したい場合は、&msdn(netfx,member,System.Array.GetLength){GetLengthメソッド};を呼び出します。 取得したい次元の番号を指定してGetLengthメソッドを呼び出すことで、多次元配列におけるその次元の長さが返されます。 GetLengthメソッドでは、最初の次元は0、その次の次元は1として扱われるため、例えば3次元配列の場合は0~2の値を次元の番号として指定します。 1次元配列に対してもGetLengthメソッドを呼び出すことは出来ますが、返される結果はLengthプロパティと同じです。
+

          
+
また、&msdn(netfx,member,System.Array.Rank){Rankプロパティ};を参照することで、多次元配列の次元数・次元の高さを取得できます。 1次元配列では1、2次元配列では2が返されます。
+

          
+
#tabpage(C#)
+
#code(cs,多次元配列の全要素数・次元数・次元毎の長さの取得){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 5個の要素を持つ1次元配列
+
    int[] arr = new int[5];
+

          
+
    Console.WriteLine("arr.Length = {0}", arr.Length);
+
    Console.WriteLine("arr.Rank = {0}", arr.Rank);
+
    Console.WriteLine("arr = {0}", arr.GetLength(0));
+
    Console.WriteLine();
+

          
+
    // 3×4個の要素を持つ2次元配列
+
    int[,] matrix = new int[3, 4];
+

          
+
    Console.WriteLine("matrix.Length = {0}", matrix.Length);
+
    Console.WriteLine("matrix.Rank = {0}", matrix.Rank);
+
    Console.WriteLine("matrix = {0}×{1}", matrix.GetLength(0), matrix.GetLength(1));
+
    Console.WriteLine();
+

          
+
    // 4×2×3個の要素を持つ3次元配列
+
    int[,,] cube = new int[4, 2, 3];
+

          
+
    Console.WriteLine("cube.Length = {0}", cube.Length);
+
    Console.WriteLine("cube.Rank = {0}", cube.Rank);
+
    Console.WriteLine("cube = {0}×{1}×{2}", cube.GetLength(0), cube.GetLength(1), cube.GetLength(2));
+
    Console.WriteLine();
+

          
+
    // 2×2×2×2個の要素を持つ4次元配列
+
    int[,,,] tesseract = new int[2, 2, 2, 2];
+

          
+
    Console.WriteLine("tesseract.Length = {0}", tesseract.Length);
+
    Console.WriteLine("tesseract.Rank = {0}", tesseract.Rank);
+
    Console.WriteLine("tesseract = {0}×{1}×{2}×{3}", tesseract.GetLength(0), tesseract.GetLength(1), tesseract.GetLength(2), tesseract.GetLength(3));
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,多次元配列の全要素数・次元数・次元毎の長さの取得){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 5個の要素を持つ1次元配列
+
    Dim arr(4) As Integer
+

          
+
    Console.WriteLine("arr.Length = {0}", arr.Length)
+
    Console.WriteLine("arr.Rank = {0}", arr.Rank)
+
    Console.WriteLine("arr = {0}", arr.GetLength(0))
+
    Console.WriteLine()
+

          
+
    ' 3×4個の要素を持つ2次元配列を作成
+
    Dim matrix(2, 3) As Integer
+

          
+
    Console.WriteLine("matrix.Length = {0}", matrix.Length)
+
    Console.WriteLine("matrix.Rank = {0}", matrix.Rank)
+
    Console.WriteLine("matrix = {0}×{1}", matrix.GetLength(0), matrix.GetLength(1))
+
    Console.WriteLine()
+

          
+
    ' 4×2×3個の要素を持つ3次元配列
+
    Dim cube(3, 1, 2) As Integer
+

          
+
    Console.WriteLine("cube.Length = {0}", cube.Length)
+
    Console.WriteLine("cube.Rank = {0}", cube.Rank)
+
    Console.WriteLine("cube = {0}×{1}×{2}", cube.GetLength(0), cube.GetLength(1), cube.GetLength(2))
+
    Console.WriteLine()
+

          
+
    ' 2×2×2×2個の要素を持つ4次元配列
+
    Dim tesseract(1, 1, 1, 1) As Integer
+

          
+
    Console.WriteLine("tesseract.Length = {0}", tesseract.Length)
+
    Console.WriteLine("tesseract.Rank = {0}", tesseract.Rank)
+
    Console.WriteLine("tesseract = {0}×{1}×{2}×{3}", tesseract.GetLength(0), tesseract.GetLength(1), tesseract.GetLength(2), tesseract.GetLength(3))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
arr.Length = 5
+
arr.Rank = 1
+
arr = 5
+

          
+
matrix.Length = 12
+
matrix.Rank = 2
+
matrix = 3×4
+

          
+
cube.Length = 24
+
cube.Rank = 3
+
cube = 4×2×3
+

          
+
tesseract.Length = 16
+
tesseract.Rank = 4
+
tesseract = 2×2×2×2
+
}}
+

          
+

          
+

          
+
**要素の列挙
+
多次元配列も1次元配列と同様for文・foreach文で列挙することが出来ます。 ただ、foreach文で列挙する場合は注意が必要で、行や列ごとといった部分配列が列挙されるのではなく、次元が平坦化された1次元の数列として列挙されます。 この際、多段配列内の各要素は、より高い次元にあるインデックスの小さい要素から順に列挙されます。 多次元配列から行や列ごとに要素を抽出したい場合は、foreach文ではなくfor文でインデックスを指定して列挙する必要があります。
+

          
+
#tabpage(C#)
+
#code(cs,2次元配列の列挙){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 3×4個の要素を持つ2次元配列
+
    int[,] matrix = {
+
      {0, 1, 2, 3},
+
      {4, 5, 6, 7},
+
      {8, 9, 10, 11},
+
    };
+

          
+
    // for文を使って列挙
+
    for (int d1 = 0; d1 < matrix.GetLength(0); d1++) {
+
      Console.Write("( ");
+
      for (int d2 = 0; d2 < matrix.GetLength(1); d2++) {
+
        Console.Write("{0}, ", matrix[d1, d2]);
+
      }
+
      Console.WriteLine("), ");
+
    }
+
    Console.WriteLine();
+

          
+
    // foreach文を使って列挙
+
    foreach (int elem in matrix) {
+
      Console.Write("{0}, ", elem);
+
    }
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,2次元配列の列挙){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 3×4個の要素を持つ2次元配列
+
    Dim matrix As Integer(,) = { _
+
      {0, 1, 2, 3}, _
+
      {4, 5, 6, 7}, _
+
      {8, 9, 10, 11} _
+
    }
+

          
+
    ' Forステートメントを使って列挙
+
    For d1 As Integer = 0 To matrix.GetLength(0) - 1
+
      Console.Write("( ")
+
      For d2 As Integer = 0 To matrix.GetLength(1) - 1
+
        Console.Write("{0}, ", matrix(d1, d2))
+
      Next
+
      Console.WriteLine("), ")
+
    Next
+
    Console.WriteLine()
+

          
+
    ' For Eachステートメントを使って列挙
+
    For Each elem As Integer In matrix
+
      Console.Write("{0}, ", elem)
+
    Next
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
( 0, 1, 2, 3, ), 
+
( 4, 5, 6, 7, ), 
+
( 8, 9, 10, 11, ), 
+

          
+
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 
+
}}
+

          
+
#tabpage(C#)
+
#code(cs,3次元配列の列挙){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 4×2×3個の要素を持つ3次元配列
+
    int[,,] cube = {
+
      {  { 0,  1,  2},  { 3,  4,  5}  },
+
      {  { 6,  7,  8},  { 9, 10, 11}  },
+
      {  {12, 13, 14},  {15, 16, 17}  },
+
      {  {18, 19, 20},  {21, 22, 23}  },
+
    };
+

          
+
    // for文を使って列挙
+
    for (int d1 = 0; d1 < cube.GetLength(0); d1++) {
+
      Console.Write("{ ");
+
      for (int d2 = 0; d2 < cube.GetLength(1); d2++) {
+
        Console.Write("( ");
+
        for (int d3 = 0; d3 < cube.GetLength(2); d3++) {
+
          Console.Write("{0}, ", cube[d1, d2, d3]);
+
        }
+
        Console.Write("), ");
+
      }
+
      Console.WriteLine("}, ");
+
    }
+
    Console.WriteLine();
+

          
+
    // foreach文を使って列挙
+
    foreach (int elem in cube) {
+
      Console.Write("{0}, ", elem);
+
    }
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,3次元配列の列挙){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 4×2×3個の要素を持つ3次元配列
+
    Dim cube As Integer(,,) = { _
+
      {  { 0,  1,  2},  { 3,  4,  5}  }, _
+
      {  { 6,  7,  8},  { 9, 10, 11}  }, _
+
      {  {12, 13, 14},  {15, 16, 17}  }, _
+
      {  {18, 19, 20},  {21, 22, 23}  } _
+
    }
+

          
+
    ' Forステートメントを使って列挙
+
    For d1 As Integer = 0 To cube.GetLength(0) - 1
+
      Console.Write("{ ")
+
      For d2 As Integer = 0 To cube.GetLength(1) - 1
+
        Console.Write("( ")
+
        For d3 As Integer = 0 To cube.GetLength(2) - 1
+
          Console.Write("{0}, ", cube(d1, d2, d3))
+
        Next
+
        Console.Write("), ")
+
      Next
+
      Console.WriteLine("}, ")
+
    Next
+
    Console.WriteLine()
+

          
+
    ' For Eachステートメントを使って列挙
+
    For Each elem As Integer In cube
+
      Console.Write("{0}, ", elem)
+
    Next
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
{ ( 0, 1, 2, ), ( 3, 4, 5, ), }, 
+
{ ( 6, 7, 8, ), ( 9, 10, 11, ), }, 
+
{ ( 12, 13, 14, ), ( 15, 16, 17, ), }, 
+
{ ( 18, 19, 20, ), ( 21, 22, 23, ), }, 
+

          
+
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 
+
}}
+

          
+
#tabpage(C#)
+
#code(cs,4次元配列の列挙){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 2×2×2×2個の要素を持つ4次元配列
+
    int[,,,] tesseract = {
+
      {  {  {0, 1},  { 2,  3}  },  {  { 4,  5},  { 6,  7}  }  },
+
      {  {  {8, 9},  {10, 11}  },  {  {12, 13},  {14, 15}  }  },
+
    };
+

          
+
    // for文を使って列挙
+
    for (int d1 = 0; d1 < tesseract.GetLength(0); d1++) {
+
      Console.Write("[ ");
+
      for (int d2 = 0; d2 < tesseract.GetLength(1); d2++) {
+
        Console.Write("{ ");
+
        for (int d3 = 0; d3 < tesseract.GetLength(2); d3++) {
+
          Console.Write("( ");
+
          for (int d4 = 0; d4 < tesseract.GetLength(3); d4++) {
+
            Console.Write("{0}, ", tesseract[d1, d2, d3, d4]);
+
          }
+
          Console.Write("), ");
+
        }
+
        Console.Write("}, ");
+
      }
+
      Console.WriteLine("], ");
+
    }
+
    Console.WriteLine();
+

          
+
    // foreach文を使って列挙
+
    foreach (int elem in tesseract) {
+
      Console.Write("{0}, ", elem);
+
    }
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,4次元配列の列挙){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 2×2×2×2個の要素を持つ4次元配列
+
    Dim tesseract As Integer(,,,) = { _
+
      {  {  {0, 1},  { 2,  3}  },  {  { 4,  5},  { 6,  7}  }  }, _
+
      {  {  {8, 9},  {10, 11}  },  {  {12, 13},  {14, 15}  }  } _
+
    }
+

          
+
    ' Forステートメントを使って列挙
+
    For d1 As Integer = 0 To tesseract.GetLength(0) - 1
+
      Console.Write("[ ")
+
      For d2 As Integer = 0 To tesseract.GetLength(1) - 1
+
        Console.Write("{ ")
+
        For d3 As Integer = 0 To tesseract.GetLength(2) - 1
+
          Console.Write("( ")
+
          For d4 As Integer = 0 To tesseract.GetLength(3) - 1
+
            Console.Write("{0}, ", tesseract(d1, d2, d3, d4))
+
          Next
+
          Console.Write("), ")
+
        Next
+
        Console.Write("}, ")
+
      Next
+
      Console.WriteLine("], ")
+
    Next
+
    Console.WriteLine()
+

          
+
    ' For Eachステートメントを使って列挙
+
    For Each elem As Integer In tesseract
+
      Console.Write("{0}, ", elem)
+
    Next
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
[ { ( 0, 1, ), ( 2, 3, ), }, { ( 4, 5, ), ( 6, 7, ), }, ], 
+
[ { ( 8, 9, ), ( 10, 11, ), }, { ( 12, 13, ), ( 14, 15, ), }, ], 
+

          
+
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 
+
}}
+

          
+

          
+

          
+
**任意の次元数の配列を扱う例
+
次の例は、Lengthプロパティ・Rankプロパティ・GetLengthメソッドなどと組み合わせて多次元配列を扱う例です。 このコードでは、任意の次元数・要素数の多次元配列を引数にとり、その多次元配列の次元・長さ・要素数・格納されている全要素を表示するメソッドを実装しています。 どのような配列もArrayクラスから暗黙的に派生しているので、引数の型をArrayとすることで任意の配列を受け取れるようにしています。 また、配列内の全要素はforeach文と同じ順で列挙されるようにしています。
+

          
+
なお、このコードで使用している&msdn(netfx,member,System.Array.GetValue){GetValueメソッド};は、引数としてインデックスを渡すことにより、配列内の該当するインデックスの値を取得することが出来るメソッドです。 詳しくは[[programming/netfx/arrays/2_operations#Array.CreateInstance]]で解説しています。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
class Sample {
+
  static void Print(Array arr)
+
  {
+
    Console.WriteLine("次元: {0}", arr.Rank);
+

          
+
    Console.Write("長さ: ");
+

          
+
    for (int d = 0; d < arr.Rank; d++) {
+
      if (0 < d)
+
        Console.Write("×{0}", arr.GetLength(d));
+
      else
+
        Console.Write("{0}", arr.GetLength(d));
+
    }
+

          
+
    Console.WriteLine();
+

          
+
    Console.WriteLine("要素数: {0}", arr.Length);
+

          
+
    Console.Write("要素: ");
+

          
+
    // 取得したい要素のインデックスを指定するための配列
+
    int[] indices = new int[arr.Rank];
+

          
+
    for (;;) {
+
      // [step1] step3でインデックスをインクリメントした結果、各次元の長さに達したかどうか調べる
+
      for (int d = arr.Rank - 1; 0 <= d; d--) {
+
        if (arr.GetLength(d) <= indices[d]) {
+
          // d次元目のインデックスがd次元目の長さを越えている場合
+
          if (d == 0) {
+
            // 1次元目(d = 0)の場合は、インクリメントした結果が1次元目の長さに達しているので終了する
+
            Console.WriteLine();
+
            return;
+
          }
+
          else {
+
            // d次元目のインデックスを0に戻し、一つ低い次元(d - 1次元)のインデックスをインクリメントする
+
            indices[d] = 0;
+
            indices[d - 1]++;
+
          }
+
        }
+
      }
+

          
+
      // [step2] 指定されたインデックスの要素を取得して表示
+
      Console.Write("{0}, ", arr.GetValue(indices));
+

          
+
      // [step3] もっとも高い次元のインデックスをインクリメント
+
      indices[arr.Rank - 1]++;
+
    }
+
  }
+

          
+
  static void Main()
+
  {
+
    // 5個の要素を持つ1次元配列
+
    int[] arr = {
+
      0, 1, 2, 3, 4,
+
    };
+

          
+
    Print(arr);
+
    Console.WriteLine();
+

          
+
    // 3×4個の要素を持つ2次元配列
+
    int[,] matrix = {
+
      {0, 1, 2, 3},
+
      {4, 5, 6, 7},
+
      {8, 9, 10, 11},
+
    };
+

          
+
    Print(matrix);
+
    Console.WriteLine();
+

          
+
    // 4×2×3個の要素を持つ3次元配列
+
    int[,,] cube = {
+
      {  { 0,  1,  2},  { 3,  4,  5}  },
+
      {  { 6,  7,  8},  { 9, 10, 11}  },
+
      {  {12, 13, 14},  {15, 16, 17}  },
+
      {  {18, 19, 20},  {21, 22, 23}  },
+
    };
+

          
+
    Print(cube);
+
    Console.WriteLine();
+

          
+
    // 2×2×2×2個の要素を持つ4次元配列
+
    int[,,,] tesseract = {
+
      {  {  {0, 1},  { 2,  3}  },  {  { 4,  5},  { 6,  7}  }  },
+
      {  {  {8, 9},  {10, 11}  },  {  {12, 13},  {14, 15}  }  },
+
    };
+

          
+
    Print(tesseract);
+
    Console.WriteLine();
+

          
+
    // 1×1×1×1×1個の要素を持つ5次元配列
+
    Print(new int[1, 1, 1, 1, 1]);
+
    Console.WriteLine();
+

          
+
    // 1×0×1×0×1×0個の要素を持つ6次元配列
+
    Print(new int[1, 0, 1, 0, 1, 0]);
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Print(ByVal arr As Array)
+
    Console.WriteLine("次元: {0}", arr.Rank)
+

          
+
    Console.Write("長さ: ")
+

          
+
    For d As Integer = 0 To arr.Rank - 1
+
      If 0 < d Then
+
        Console.Write("×{0}", arr.GetLength(d))
+
      Else
+
        Console.Write("{0}", arr.GetLength(d))
+
      End If
+
    Next
+

          
+
    Console.WriteLine()
+

          
+
    Console.WriteLine("要素数: {0}", arr.Length)
+

          
+
    Console.Write("要素: ")
+

          
+
    ' 取得したい要素のインデックスを指定するための配列
+
    Dim indices(arr.Rank - 1) As Integer
+

          
+
    Do
+
      ' [step1] step3でインデックスをインクリメントした結果、各次元の長さに達したかどうか調べる
+
      For d As Integer = arr.Rank - 1 To 0 Step -1
+
        If arr.GetLength(d) <= indices(d) Then
+
          ' d次元目のインデックスがd次元目の長さを越えている場合
+
          If d = 0 Then
+
            ' 1次元目(d = 0)の場合は、インクリメントした結果が1次元目の長さに達しているので終了する
+
            Console.WriteLine()
+
            Return
+
          Else
+
            ' d次元目のインデックスを0に戻し、一つ低い次元(d - 1次元)のインデックスをインクリメントする
+
            indices(d) = 0
+
            indices(d - 1) += 1
+
          End if
+
        End If
+
      Next
+

          
+
      ' [step2] 指定されたインデックスの要素を取得して表示
+
      Console.Write("{0}, ", arr.GetValue(indices))
+

          
+
      ' [step3] もっとも高い次元のインデックスをインクリメント
+
      indices(arr.Rank - 1) += 1
+
    Loop
+
  End Sub
+

          
+
  Shared Sub Main()
+
    ' 5個の要素を持つ1次元配列
+
    Dim arr As Integer() = { _
+
      0, 1, 2, 3, 4 _
+
    }
+

          
+
    Print(arr)
+
    Console.WriteLine()
+

          
+
    ' 3×4個の要素を持つ2次元配列
+
    Dim matrix As Integer(,) = { _
+
      {0, 1, 2, 3}, _
+
      {4, 5, 6, 7}, _
+
      {8, 9, 10, 11} _
+
    }
+

          
+
    Print(matrix)
+
    Console.WriteLine()
+

          
+
    ' 4×2×3個の要素を持つ3次元配列
+
    Dim cube As Integer(,,) = { _
+
      {  { 0,  1,  2},  { 3,  4,  5}  }, _
+
      {  { 6,  7,  8},  { 9, 10, 11}  }, _
+
      {  {12, 13, 14},  {15, 16, 17}  }, _
+
      {  {18, 19, 20},  {21, 22, 23}  } _
+
    }
+

          
+
    Print(cube)
+
    Console.WriteLine()
+

          
+
    ' 2×2×2×2個の要素を持つ4次元配列
+
    Dim tesseract As Integer(,,,) = { _
+
      {  {  {0, 1},  { 2,  3}  },  {  { 4,  5},  { 6,  7}  }  }, _
+
      {  {  {8, 9},  {10, 11}  },  {  {12, 13},  {14, 15}  }  } _
+
    }
+

          
+
    Print(tesseract)
+
    Console.WriteLine()
+

          
+
    ' 1×1×1×1×1個の要素を持つ5次元配列
+
    Print(New Integer(0, 0, 0, 0, 0) {})
+
    Console.WriteLine()
+

          
+
    ' 1×0×1×0×1×0個の要素を持つ6次元配列
+
    Print(New Integer(0, -1, 0, -1, 0, -1) {})
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
次元: 1
+
長さ: 5
+
要素数: 5
+
要素: 0, 1, 2, 3, 4, 
+

          
+
次元: 2
+
長さ: 3×4
+
要素数: 12
+
要素: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 
+

          
+
次元: 3
+
長さ: 4×2×3
+
要素数: 24
+
要素: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 
+

          
+
次元: 4
+
長さ: 2×2×2×2
+
要素数: 16
+
要素: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 
+

          
+
次元: 5
+
長さ: 1×1×1×1×1
+
要素数: 1
+
要素: 0, 
+

          
+
次元: 6
+
長さ: 1×0×1×0×1×0
+
要素数: 0
+
要素: 
+

          
+
}}
+

          
+

          
+

          
+
*ジャグ配列 (多段配列)
+
**宣言・作成・要素の参照
+
2段のジャグ配列を宣言・作成し、要素を参照する例について見てみます。 次の例では、1段目の長さが3、2段目の長さが各々3, 2, 4の計9個の要素を持つ2段のジャグ配列を作成しています。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 1段目の長さが3である2段のジャグ配列を作成
+
    int[][] jagged = new int[3][];
+

          
+
    // 作成したジャグ配列の1段目に、2段目となる配列を代入
+
    jagged[0] = new int[3]; // 1段目の0番目に長さが3の配列を代入
+
    jagged[1] = new int[2]; // 1段目の1番目に長さが2の配列を代入
+
    jagged[2] = new int[4]; // 1段目の2番目に長さが4の配列を代入
+

          
+
    // 1段目のインデックスが0、2段目のインデックスが0の要素に値を設定
+
    jagged[0][0] = 0;
+

          
+
    // 1段目のインデックスが2、2段目のインデックスが3の要素に値を設定
+
    jagged[2][3] = 8;
+
  }
+
}
+

          
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 1段目の長さが3である2段のジャグ配列を作成
+
    Dim jagged(2)() As Integer
+

          
+
    ' 作成したジャグ配列の1段目に、2段目となる配列を代入
+
    jagged(0) = New Integer(2) {} ' 1段目の0番目に長さが3の配列を代入
+
    jagged(1) = New Integer(1) {} ' 1段目の1番目に長さが2の配列を代入
+
    jagged(2) = New Integer(3) {} ' 1段目の2番目に長さが4の配列を代入
+

          
+
    ' 1段目のインデックスが0、2段目のインデックスが0の要素に値を設定
+
    jagged(0)(0) = 0
+

          
+
    ' 1段目のインデックスが2、2段目のインデックスが3の要素に値を設定
+
    jagged(2)(3) = 8
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
2段のジャグ配列を宣言する場合は、1段目の要素数(またはインデックスの最大値)と、要素数を空にした2段目を括弧を連ねて記述します。 2段目に要素数を指定することは出来ません。 このように宣言されたジャグ配列では、2段目の配列はまだ作成されておらずヌル参照(null/Nothing)となっています。 そこからさらに2段目となる配列を1段目に代入していくことで、2段のジャグ配列を構成することが出来ます。
+

          
+
2段のジャグ配列内の各要素を参照する場合は、1段目と2段目のインデックスを括弧を連ねて記述します。 上記のコードで作成される2段のジャグ配列を図式化すると次のようになります。 1段目を縦方向、2段目を横方向で表しています。
+

          
+
|*1段目の長さが3の2段のジャグ配列のイメージ
+
|jagged[0] → &column(delim=/){jagged[0][0]/jagged[0][1]/jagged[0][2]/};|
+
|jagged[1] → &column(delim=/){jagged[1][0]/jagged[1][1]};|
+
|jagged[2] → &column(delim=/){jagged[2][0]/jagged[2][1]/jagged[2][2]/jagged[2][3]/};|
+

          
+
3段以上のジャグ配列を宣言・作成する場合も同様に、まず1段目の要素数のみを指定し、段数分だけ括弧を連ねて記述します。 そこから2段目となる配列の代入、さらにそこへ3段目となる配列を代入…と繰り替えしていきます。 要素を参照する場合も同様に、[&var{1段目};][&var{2段目};][&var{3段目};][…] と段数分だけ括弧を連ねて記述します。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 1段目の長さが3である3段のジャグ配列を作成
+
    int[][][] doubleNested = new int[3][][];
+

          
+
    // 1段目に2段目となる配列を代入
+
    doubleNested[2] = new int[2][]; // 1段目の2番目に長さが2で2段のジャグ配列を代入
+

          
+
    // 2段目に3段目となる配列を代入
+
    doubleNested[2][0] = new int[4]; // 1段目の0番目、2段目の0番目に長さが4の配列を代入
+

          
+
    // 3段目の要素に値を代入
+
    doubleNested[2][0][3] = 5;
+

          
+

          
+

          
+
    // 1段目の長さが2である4段のジャグ配列を作成
+
    int[][][][] tripleNested = new int[2][][][];
+

          
+
    // 1段目に2段目となる配列を代入
+
    tripleNested[1] = new int[1][][]; // 1段目の1番目に長さが1で3段のジャグ配列を代入
+

          
+
    // 2段目に3段目となる配列を代入
+
    tripleNested[1][0] = new int[3][]; // 1段目の1番目、2段目の0番目に長さが3で2段のジャグ配列を代入
+

          
+
    // 3段目に4段目となる配列を代入
+
    tripleNested[1][0][2] = new int[2]; // 1段目の1番目、2段目の0番目、3段目の2番目に長さが2の配列を代入
+

          
+
    // 4段目の要素に値を代入
+
    tripleNested[1][0][2][1] = 16;
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 1段目の長さが3である3段のジャグ配列を作成
+
    Dim doubleNested(2)()() As Integer
+

          
+
    ' 1段目に2段目となる配列を代入
+
    doubleNested(2) = New Integer(1)() {} ' 1段目の2番目に長さが2で2段のジャグ配列を代入
+

          
+
    ' 2段目に3段目となる配列を代入
+
    doubleNested(2)(0) = New Integer(3) {} ' 1段目の0番目、2段目の0番目に長さが4の配列を代入
+

          
+
    ' 3段目の要素に値を代入
+
    doubleNested(2)(0)(3) = 5
+

          
+

          
+

          
+
    ' 1段目の長さが2である4段のジャグ配列を作成
+
    Dim tripleNested(1)()()() As Integer
+

          
+
    ' 1段目に2段目となる配列を代入
+
    tripleNested(1) = New Integer(0)()() {} ' 1段目の1番目に長さが1で3段のジャグ配列を代入
+

          
+
    ' 2段目に3段目となる配列を代入
+
    tripleNested(1)(0) = New Integer(2)() {} ' 1段目の1番目、2段目の0番目に長さが3で2段のジャグ配列を代入
+

          
+
    ' 3段目に4段目となる配列を代入
+
    tripleNested(1)(0)(2) = New Integer(1) {} ' 1段目の1番目、2段目の0番目、3段目の2番目に長さが2の配列を代入
+

          
+
    ' 4段目の要素に値を代入
+
    tripleNested(1)(0)(2)(1) = 16
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
ジャグ配列は''配列の配列''であることから、宣言等の記述を次のように読み替えることも出来ます。
+

          
+
|~配列|~記述|~読み替え|h
+
|2段のジャグ配列|int[][]|{{
+
''&color(red){int};'' 型の 配列 ''&color(red){[]};'' の配列 ''&color(red){[]};''
+
もしくは
+
1段のジャグ配列 &color(red){''int[]''}; に 配列 ''&color(red){[]};'' を含めるようにしたもの
+
}}|
+
|3段のジャグ配列|int[][][]|{{
+
''&color(red){int};'' 型の 配列 ''&color(red){[]};'' の配列 ''&color(red){[]};'' の配列 ''&color(red){[]};''
+
もしくは
+
2段のジャグ配列 &color(red){''int[][]''}; に 配列 ''&color(red){[]};'' を含めるようにしたもの
+
}}|
+
|4段のジャグ配列|int[][][][]|{{
+
''&color(red){int};'' 型の 配列 ''&color(red){[]};'' の配列 ''&color(red){[]};'' の配列 ''&color(red){[]};'' の配列 ''&color(red){[]};''
+
もしくは
+
3段のジャグ配列 &color(red){''int[][][]''}; に 配列 ''&color(red){[]};'' を含めるようにしたもの
+
}}|
+

          
+
宣言されているものと異なる段数の配列を代入しようとするとコンパイル時にエラーとなります。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 3段のジャグ配列
+
    int[][][] doubleNested = new int[3][][];
+

          
+
    // 2段のジャグ配列を格納する変数
+
    int[][] jagged;
+

          
+
    // sample.cs(13,14): error CS0029: 型 'int[][][]' を型 'int[][]' に暗黙的に変換できません。
+
    jagged = doubleNested;
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 3段のジャグ配列
+
    Dim doubleNested(2)()() As Integer
+

          
+
    ' 2段のジャグ配列を格納する変数
+
    Dim jagged()() As Integer
+

          
+
    ' E:\sample.vb(12) : error BC30332: 'Integer の 1 次元配列 の 1 次元配列' は 'Integer の 1 次元配列' から派生していないため、型 'Integer の 1 次元配列 の 1 次元配列 の 1 次元配列' の値を 'Integer の 1 次元配列 の 1 次元配列' に変換できません。
+
    jagged = doubleNested
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+

          
+

          
+
**初期化
+
ジャグ配列の場合でも配列初期化子を使って初期化することが出来ます。 配列初期化子を使って初期化する場合、多次元配列の場合と同様の記述が出来ますが、1段目はnewを省略して記述出来るのに対し、2段目以降はnewを省略して記述することは出来ないという点に注意が必要です。 次の例では先ほどと同様の、1段目の長さが3、2段目の長さが各々3, 2, 4の計9個の要素を持つ2段のジャグ配列を作成すると同時に初期化を行っています。
+

          
+
#tabpage(C#)
+
#code(cs,2段のジャグ配列の初期化){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 1段目の長さが3、2段目の長さが各々3, 2, 4の2段のジャグ配列を作成
+
    int[][] jagged = {
+
      new int[] {0, 1, 2},
+
      new int[] {3, 4},
+
      new int[] {5, 6, 7, 8},
+
    };
+

          
+
    Console.WriteLine("jagged[0][0] = {0}", jagged[0][0]);
+
    Console.WriteLine("jagged[0][1] = {0}", jagged[0][1]);
+
    Console.WriteLine("jagged[1][0] = {0}", jagged[1][0]);
+
    Console.WriteLine("jagged[2][3] = {0}", jagged[2][3]);
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,2段のジャグ配列の初期化){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 1段目の長さが3、2段目の長さが各々3, 2, 4の2段のジャグ配列を作成
+
    Dim jagged()() As Integer = { _
+
      New Integer() {0, 1, 2}, _
+
      New Integer() {3, 4}, _
+
      New Integer() {5, 6, 7, 8} _
+
    }
+

          
+
    Console.WriteLine("jagged(0)(0) = {0}", jagged(0)(0))
+
    Console.WriteLine("jagged(0)(1) = {0}", jagged(0)(1))
+
    Console.WriteLine("jagged(1)(0) = {0}", jagged(1)(0))
+
    Console.WriteLine("jagged(2)(3) = {0}", jagged(2)(3))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
jagged[0][0] = 0
+
jagged[0][1] = 1
+
jagged[1][0] = 3
+
jagged[2][3] = 8
+
}}
+

          
+
このコードで作成・初期化される2段のジャグ配列を図式化すると次のようになります。
+

          
+
|*初期化後に2段のジャグ配列へ格納される値のイメージ
+
|jagged[0] → &column{0, 1, 2};|
+
|jagged[1] → &column{3, 4};|
+
|jagged[2] → &column{5, 6, 7, 8};|
+

          
+
3段以上のジャグ配列も同様にして初期化することが出来ます。 配列の中に配列を含めるよう入れ子に記述していくことで多段のジャグ配列を初期化できます。
+

          
+
#tabpage(C#)
+
#code(cs,3段のジャグ配列の初期化){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 3段のジャグ配列
+
    int[][][] doubleNested = {
+
      new int[][] {
+
        new int[] {0, 1, 2},
+
        new int[] {3, 4},
+
        new int[] {5, 6, 7, 8},
+
      },
+
      new int[][] {
+
        new int[] {9, 10},
+
        new int[] {11, 12, 13, 14},
+
      },
+
      new int[][] {
+
        new int[] {15, 16, 17},
+
        new int[] {18},
+
        new int[] {19, 20},
+
        new int[] {21, 22},
+
      },
+
    };
+

          
+
    Console.WriteLine("doubleNested[0][0][0] = {0}", doubleNested[0][0][0]);
+
    Console.WriteLine("doubleNested[0][2][3] = {0}", doubleNested[0][2][3]);
+
    Console.WriteLine("doubleNested[1][0][0] = {0}", doubleNested[1][0][0]);
+
    Console.WriteLine("doubleNested[2][3][1] = {0}", doubleNested[2][3][1]);
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,3段のジャグ配列の初期化){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 3段のジャグ配列
+
    Dim doubleNested()()() As Integer = { _
+
      New Integer()() { _
+
        New Integer() {0, 1, 2}, _
+
        New Integer() {3, 4}, _
+
        New Integer() {5, 6, 7, 8} _
+
      }, _
+
      New Integer()() { _
+
        New Integer() {9, 10}, _
+
        New Integer() {11, 12, 13, 14} _
+
      }, _
+
      New Integer()() { _
+
        New Integer() {15, 16, 17}, _
+
        New Integer() {18}, _
+
        New Integer() {19, 20}, _
+
        New Integer() {21, 22} _
+
      } _
+
    }
+

          
+
    Console.WriteLine("doubleNested(0)(0)(0) = {0}", doubleNested(0)(0)(0))
+
    Console.WriteLine("doubleNested(0)(2)(3) = {0}", doubleNested(0)(2)(3))
+
    Console.WriteLine("doubleNested(1)(0)(0) = {0}", doubleNested(1)(0)(0))
+
    Console.WriteLine("doubleNested(2)(3)(1) = {0}", doubleNested(2)(3)(1))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
doubleNested[0][0][0] = 0
+
doubleNested[0][2][3] = 8
+
doubleNested[1][0][0] = 9
+
doubleNested[2][3][1] = 22
+
}}
+

          
+

          
+

          
+
**長さの取得
+
多次元配列とは異なり、Lengthプロパティを参照しても全要素を取得することは出来ません。 ジャグ配列の場合、Lengthプロパティは1次元配列と同様、''1段目の長さ''を返します。 また、ジャグ配列では各段で長さが異なるため、GetLengthメソッドを使って2段目以降の長さを取得するといったことも出来ません。
+

          
+
#tabpage(C#)
+
#code(cs,ジャグ配列の長さの取得){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 1段目の長さが3である2段のジャグ配列
+
    int[][] jagged = new int[3][];
+

          
+
    Console.WriteLine("jagged.Length = {0}", jagged.Length);
+

          
+
    // 1段目の長さが3である3段のジャグ配列
+
    int[][][] doubleNested = new int[3][][];
+

          
+
    Console.WriteLine("doubleNested.Length = {0}", doubleNested.Length);
+

          
+
    // 1段目の長さが2である4段のジャグ配列
+
    int[][][][] tripleNested = new int[2][][][];
+

          
+
    Console.WriteLine("tripleNested.Length = {0}", tripleNested.Length);
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,ジャグ配列の長さの取得){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 1段目の長さが3である2段のジャグ配列
+
    Dim jagged(2)() As Integer
+

          
+
    Console.WriteLine("jagged.Length = {0}", jagged.Length)
+

          
+
    ' 1段目の長さが3である3段のジャグ配列
+
    Dim doubleNested(2)()() As Integer
+

          
+
    Console.WriteLine("doubleNested.Length = {0}", doubleNested.Length)
+

          
+
    ' 1段目の長さが2である4段のジャグ配列
+
    Dim tripleNested(1)()()() As Integer
+

          
+
    Console.WriteLine("tripleNested.Length = {0}", tripleNested.Length)
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
jagged.Length = 3
+
doubleNested.Length = 3
+
tripleNested.Length = 2
+
}}
+

          
+
2段目以降の長さを取得する場合は、ジャグ配列内に格納されている配列のLengthプロパティを個別に参照する必要があります。
+

          
+
#tabpage(C#)
+
#code(cs,ジャグ配列の2段目の長さの取得){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 2段のジャグ配列
+
    int[][] jagged = {
+
      new int[] {0, 1, 2},
+
      new int[] {3, 4},
+
      new int[] {5, 6, 7, 8},
+
    };
+

          
+
    Console.WriteLine("jagged[0].Length = {0}", jagged[0].Length);
+
    Console.WriteLine("jagged[1].Length = {0}", jagged[1].Length);
+
    Console.WriteLine("jagged[2].Length = {0}", jagged[2].Length);
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,ジャグ配列の2段目の長さの取得){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 2段のジャグ配列
+
    Dim jagged()() As Integer = { _
+
      New Integer() {0, 1, 2}, _
+
      New Integer() {3, 4}, _
+
      New Integer() {5, 6, 7, 8} _
+
    }
+

          
+
    Console.WriteLine("jagged(0).Length = {0}", jagged(0).Length)
+
    Console.WriteLine("jagged(1).Length = {0}", jagged(1).Length)
+
    Console.WriteLine("jagged(2).Length = {0}", jagged(2).Length)
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
jagged[0].Length = 3
+
jagged[1].Length = 2
+
jagged[2].Length = 4
+
}}
+

          
+

          
+

          
+
**要素の列挙
+
ジャグ配列も1次元配列と同様for文・foreach文で列挙することが出来ます。 foreach文で列挙する場合は、多次元配列のように配列内の全要素が一つずつ列挙されるのではなく、ジャグ配列の1段目に格納されている配列が列挙されます。
+

          
+
#tabpage(C#)
+
#code(cs,2段のジャグ配列の列挙){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 2段のジャグ配列
+
    int[][] jagged = {
+
      new int[] {0, 1, 2},
+
      new int[] {3, 4},
+
      new int[] {5, 6, 7, 8},
+
    };
+

          
+
    // for文を使って列挙
+
    for (int n1 = 0; n1 < jagged.Length; n1++) {
+
      Console.Write("( ");
+
      for (int n2 = 0; n2 < jagged[n1].Length; n2++) {
+
        Console.Write("{0}, ", jagged[n1][n2]);
+
      }
+
      Console.WriteLine("), ");
+
    }
+
    Console.WriteLine();
+

          
+
    // foreach文を使って列挙
+
    foreach (int[] arr in jagged) {
+
      Console.Write("( ");
+
      foreach (int elem in arr) {
+
        Console.Write("{0}, ", elem);
+
      }
+
      Console.WriteLine("), ");
+
    }
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,2段のジャグ配列の列挙){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 2段のジャグ配列
+
    Dim jagged()() As Integer = { _
+
      New Integer() {0, 1, 2}, _
+
      New Integer() {3, 4}, _
+
      New Integer() {5, 6, 7, 8} _
+
    }
+

          
+
    ' Forステートメントを使って列挙
+
    For n1 As Integer = 0 To jagged.Length - 1
+
      Console.Write("( ")
+
      For n2 As Integer = 0 To jagged(n1).Length - 1
+
        Console.Write("{0}, ", jagged(n1)(n2))
+
      Next
+
      Console.WriteLine("), ")
+
    Next
+
    Console.WriteLine()
+

          
+
    ' For Eachステートメントを使って列挙
+
    For Each arr As Integer() In jagged
+
      Console.Write("( ")
+
      For Each elem As Integer In arr
+
        Console.Write("{0}, ", elem)
+
      Next
+
      Console.WriteLine("), ")
+
    Next
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
( 0, 1, 2, ), 
+
( 3, 4, ), 
+
( 5, 6, 7, 8, ), 
+

          
+
( 0, 1, 2, ), 
+
( 3, 4, ), 
+
( 5, 6, 7, 8, ), 
+

          
+
}}
+

          
+
#tabpage(C#)
+
#code(cs,3段のジャグ配列の列挙){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    // 3段のジャグ配列
+
    int[][][] doubleNested = {
+
      new int[][] {
+
        new int[] {0, 1, 2},
+
        new int[] {3, 4},
+
        new int[] {5, 6, 7, 8},
+
      },
+
      new int[][] {
+
        new int[] {9, 10},
+
        new int[] {11, 12, 13, 14},
+
      },
+
      new int[][] {
+
        new int[] {15, 16, 17},
+
        new int[] {18},
+
        new int[] {19, 20},
+
        new int[] {21, 22},
+
      },
+
    };
+

          
+
    // for文を使って列挙
+
    for (int n1 = 0; n1 < doubleNested.Length; n1++) {
+
      Console.Write("{ ");
+
      for (int n2 = 0; n2 < doubleNested[n1].Length; n2++) {
+
        Console.Write("( ");
+
        for (int n3 = 0; n3 < doubleNested[n1][n2].Length; n3++) {
+
          Console.Write("{0}, ", doubleNested[n1][n2][n3]);
+
        }
+
        Console.Write("), ");
+
      }
+
      Console.WriteLine("}, ");
+
    }
+
    Console.WriteLine();
+

          
+
    // foreach文を使って列挙
+
    foreach (int[][] jagged in doubleNested) {
+
      Console.Write("{ ");
+
      foreach (int[] arr in jagged) {
+
        Console.Write("( ");
+
        foreach (int elem in arr) {
+
          Console.Write("{0}, ", elem);
+
        }
+
        Console.Write("), ");
+
      }
+
      Console.WriteLine("}, ");
+
    }
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,3段のジャグ配列の列挙){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' 3段のジャグ配列
+
    Dim doubleNested()()() As Integer = { _
+
      New Integer()() { _
+
        New Integer() {0, 1, 2}, _
+
        New Integer() {3, 4}, _
+
        New Integer() {5, 6, 7, 8} _
+
      }, _
+
      New Integer()() { _
+
        New Integer() {9, 10}, _
+
        New Integer() {11, 12, 13, 14} _
+
      }, _
+
      New Integer()() { _
+
        New Integer() {15, 16, 17}, _
+
        New Integer() {18}, _
+
        New Integer() {19, 20}, _
+
        New Integer() {21, 22} _
+
      } _
+
    }
+

          
+
    ' Forステートメントを使って列挙
+
    For n1 As Integer = 0 To doubleNested.Length - 1
+
      Console.Write("{ ")
+
      For n2 As Integer = 0 To doubleNested(n1).Length - 1
+
        Console.Write("( ")
+
        For n3 As Integer = 0 To doubleNested(n1)(n2).Length - 1
+
          Console.Write("{0}, ", doubleNested(n1)(n2)(n3))
+
        Next
+
        Console.Write("), ")
+
      Next
+
      Console.WriteLine("}, ")
+
    Next
+
    Console.WriteLine()
+

          
+
    ' For Eachステートメントを使って列挙
+
    For Each jagged As Integer()() In doubleNested
+
      Console.Write("{ ")
+
      For Each arr As Integer() In jagged
+
        Console.Write("( ")
+
        For Each elem As Integer In arr
+
          Console.Write("{0}, ", elem)
+
        Next
+
        Console.Write("), ")
+
      Next
+
      Console.WriteLine("), ")
+
    Next
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
{ ( 0, 1, 2, ), ( 3, 4, ), ( 5, 6, 7, 8, ), }, 
+
{ ( 9, 10, ), ( 11, 12, 13, 14, ), }, 
+
{ ( 15, 16, 17, ), ( 18, ), ( 19, 20, ), ( 21, 22, ), }, 
+

          
+
{ ( 0, 1, 2, ), ( 3, 4, ), ( 5, 6, 7, 8, ), }, 
+
{ ( 9, 10, ), ( 11, 12, 13, 14, ), }, 
+
{ ( 15, 16, 17, ), ( 18, ), ( 19, 20, ), ( 21, 22, ), }, 
+

          
+
}}
+

          
+

          
+

          
+
#navi(..)
+