配列&コレクション

[C#] 多次元配列の書き方や使い方をわかりやすく解説

C#で多次元配列を使用する場合、配列の次元数に応じてカンマを使って宣言します。

例えば、2次元配列はint[,]、3次元配列はint[,,]のように記述します。

配列の宣言時には、次のように要素数を指定します:int[,] array = new int[3, 4];

これは3行4列の2次元配列を作成します。

要素へのアクセスは、array[行, 列]の形式で行います。

多次元配列は、行列や座標データの管理に便利です。

C#における多次元配列の宣言方法

C#では、多次元配列を使用して、複数の次元を持つデータを効率的に管理できます。

ここでは、2次元配列と3次元配列の宣言方法、配列の初期化方法、サイズ指定について解説します。

2次元配列の宣言

2次元配列は、行と列の形式でデータを格納します。

以下のように宣言できます。

int[,] twoDimensionalArray; // 2次元配列の宣言

この場合、int型の2次元配列を宣言しています。

配列のサイズは後で指定します。

3次元配列の宣言

3次元配列は、行、列、深さの3つの次元を持つデータを格納します。

以下のように宣言できます。

int[,,] threeDimensionalArray; // 3次元配列の宣言

この場合も、int型の3次元配列を宣言しています。

配列の初期化方法

配列を宣言した後、初期化する必要があります。

以下のように初期化できます。

int[,] twoDimensionalArray = new int[3, 4]; // 3行4列の2次元配列を初期化
int[,,] threeDimensionalArray = new int[2, 3, 4]; // 2x3x4の3次元配列を初期化

このコードでは、2次元配列は3行4列、3次元配列は2x3x4のサイズで初期化されています。

配列のサイズ指定

配列のサイズは、宣言時に指定することができます。

以下のように、サイズを指定して初期化することも可能です。

int[,] twoDimensionalArray = { { 1, 2, 3 }, { 4, 5, 6 } }; // 2次元配列の初期化
int[,,] threeDimensionalArray = { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } }; // 3次元配列の初期化

この場合、2次元配列は2行3列、3次元配列は2x2x2のサイズで初期化されています。

多次元配列の要素へのアクセス

多次元配列に格納されたデータにアクセスする方法について解説します。

要素の取得方法、代入方法、そして配列の範囲外アクセスに関する注意点を見ていきましょう。

要素の取得方法

多次元配列の要素を取得するには、インデックスを指定します。

以下の例では、2次元配列の要素を取得しています。

int[,] twoDimensionalArray = { { 1, 2, 3 }, { 4, 5, 6 } }; // 2次元配列の初期化
int element = twoDimensionalArray[1, 2]; // 2行3列目の要素を取得
Console.WriteLine(element); // 出力: 6

このコードでは、twoDimensionalArray[1, 2]で2行3列目の要素を取得し、elementに格納しています。

要素の代入方法

要素に値を代入するには、同様にインデックスを指定します。

以下の例では、2次元配列の要素に新しい値を代入しています。

int[,] twoDimensionalArray = { { 1, 2, 3 }, { 4, 5, 6 } }; // 2次元配列の初期化
twoDimensionalArray[0, 1] = 10; // 1行2列目の要素に10を代入
Console.WriteLine(twoDimensionalArray[0, 1]); // 出力: 10

このコードでは、twoDimensionalArray[0, 1]に10を代入し、その後に新しい値を出力しています。

配列の範囲外アクセスの注意点

配列のインデックスは、0から始まるため、範囲外のインデックスを指定するとIndexOutOfRangeExceptionが発生します。

以下の例では、範囲外アクセスの注意点を示しています。

int[,] twoDimensionalArray = { { 1, 2, 3 }, { 4, 5, 6 } }; // 2次元配列の初期化
try
{
    int element = twoDimensionalArray[2, 0]; // 範囲外アクセス
}
catch (IndexOutOfRangeException e)
{
    Console.WriteLine("範囲外アクセス: " + e.Message); // エラーメッセージを出力
}

このコードでは、存在しないインデックス[2, 0]にアクセスしようとしたため、例外が発生し、エラーメッセージが出力されます。

配列のサイズを確認し、適切なインデックスを使用することが重要です。

多次元配列のループ処理

多次元配列の要素を操作するためには、ループ処理を使用します。

ここでは、forループとforeachループを使った要素の操作方法、さらにネストされたループの使い方について解説します。

forループを使った要素の操作

forループを使用して、2次元配列の全要素にアクセスする方法を示します。

以下の例では、2次元配列の要素を出力しています。

int[,] twoDimensionalArray = { { 1, 2, 3 }, { 4, 5, 6 } }; // 2次元配列の初期化
for (int i = 0; i < 2; i++) // 行のループ
{
    for (int j = 0; j < 3; j++) // 列のループ
    {
        Console.Write(twoDimensionalArray[i, j] + " "); // 要素を出力
    }
    Console.WriteLine(); // 行の終わりで改行
}

このコードでは、forループを使って行と列をそれぞれループし、全要素を出力しています。

foreachループを使った要素の操作

foreachループを使用して、2次元配列の要素を操作することもできます。

ただし、foreachループは配列の各要素を直接取得するため、インデックスを使用することはできません。

以下の例では、foreachループを使って要素を出力しています。

int[,] twoDimensionalArray = { { 1, 2, 3 }, { 4, 5, 6 } }; // 2次元配列の初期化
foreach (int element in twoDimensionalArray) // 各要素を取得
{
    Console.Write(element + " "); // 要素を出力
}
Console.WriteLine(); // 改行

このコードでは、foreachループを使って全要素を出力しています。

ネストされたループの使い方

ネストされたループを使用することで、より複雑な処理を行うことができます。

以下の例では、2次元配列の要素を2倍にする処理を行っています。

int[,] twoDimensionalArray = { { 1, 2, 3 }, { 4, 5, 6 } }; // 2次元配列の初期化
for (int i = 0; i < 2; i++) // 行のループ
{
    for (int j = 0; j < 3; j++) // 列のループ
    {
        twoDimensionalArray[i, j] *= 2; // 要素を2倍にする
    }
}
// 結果を出力
for (int i = 0; i < 2; i++)
{
    for (int j = 0; j < 3; j++)
    {
        Console.Write(twoDimensionalArray[i, j] + " "); // 要素を出力
    }
    Console.WriteLine(); // 行の終わりで改行
}

このコードでは、最初のforループで要素を2倍にし、次のforループでその結果を出力しています。

ネストされたループを使うことで、配列の各要素に対して複雑な処理を行うことが可能です。

多次元配列の応用例

多次元配列は、さまざまな分野でのデータ管理や計算に利用されます。

ここでは、行列の計算、画像データの管理、座標データの管理、ゲームのマップデータの管理について具体的な例を挙げて解説します。

行列の計算

行列の計算は、数学や物理学の分野でよく使用されます。

以下の例では、2つの2次元配列(行列)を加算する方法を示します。

int[,] matrixA = { { 1, 2 }, { 3, 4 } }; // 行列A
int[,] matrixB = { { 5, 6 }, { 7, 8 } }; // 行列B
int[,] resultMatrix = new int[2, 2]; // 結果を格納する行列
for (int i = 0; i < 2; i++)
{
    for (int j = 0; j < 2; j++)
    {
        resultMatrix[i, j] = matrixA[i, j] + matrixB[i, j]; // 行列の加算
    }
}
// 結果を出力
for (int i = 0; i < 2; i++)
{
    for (int j = 0; j < 2; j++)
    {
        Console.Write(resultMatrix[i, j] + " "); // 結果を出力
    }
    Console.WriteLine(); // 行の終わりで改行
}

このコードでは、行列Aと行列Bを加算し、結果をresultMatrixに格納しています。

画像データの管理

画像データは、ピクセル情報を多次元配列で管理することが一般的です。

以下の例では、グレースケール画像のピクセル値を2次元配列で表現しています。

int[,] grayscaleImage = { { 255, 128 }, { 64, 0 } }; // グレースケール画像のピクセル値
for (int i = 0; i < 2; i++)
{
    for (int j = 0; j < 2; j++)
    {
        Console.Write(grayscaleImage[i, j] + " "); // ピクセル値を出力
    }
    Console.WriteLine(); // 行の終わりで改行
}

このコードでは、2次元配列grayscaleImageに格納されたピクセル値を出力しています。

座標データの管理

座標データを多次元配列で管理することで、2D空間や3D空間の点を効率的に扱うことができます。

以下の例では、2D座標を管理するための2次元配列を示します。

int[,] coordinates = { { 1, 2 }, { 3, 4 }, { 5, 6 } }; // 2D座標データ
for (int i = 0; i < coordinates.GetLength(0); i++)
{
    Console.WriteLine($"点{i + 1}: ({coordinates[i, 0]}, {coordinates[i, 1]})"); // 座標を出力
}

このコードでは、2次元配列coordinatesに格納された座標データを出力しています。

ゲームのマップデータの管理

ゲームでは、マップデータを多次元配列で管理することが一般的です。

以下の例では、簡単なゲームマップを表現しています。

char[,] gameMap = { { 'W', 'W', 'W' }, { 'W', ' ', 'W' }, { 'W', 'W', 'W' } }; // ゲームマップ
for (int i = 0; i < gameMap.GetLength(0); i++)
{
    for (int j = 0; j < gameMap.GetLength(1); j++)
    {
        Console.Write(gameMap[i, j]); // マップを出力
    }
    Console.WriteLine(); // 行の終わりで改行
}

このコードでは、gameMapに格納されたマップデータを出力しています。

'W'は壁を、' 'は空間を表しています。

多次元配列を使用することで、ゲームのマップを簡単に管理できます。

ジャグ配列との違い

C#では、配列には多次元配列とジャグ配列の2つの主要な形式があります。

ここでは、ジャグ配列の基本、両者の使い分け、そしてジャグ配列の宣言と初期化について解説します。

ジャグ配列の基本

ジャグ配列は、各行が異なる長さを持つ配列のことを指します。

これは、配列の各要素が別の配列であるため、行ごとに異なるサイズを持つことができます。

以下の例では、ジャグ配列の基本的な構造を示します。

int[][] jaggedArray = new int[3][]; // 3行のジャグ配列を宣言
jaggedArray[0] = new int[2]; // 1行目は2列
jaggedArray[1] = new int[3]; // 2行目は3列
jaggedArray[2] = new int[1]; // 3行目は1列

このコードでは、3行のジャグ配列を宣言し、各行に異なる列数を設定しています。

多次元配列とジャグ配列の使い分け

多次元配列とジャグ配列は、データの構造に応じて使い分けることが重要です。

以下のポイントを考慮してください。

特徴多次元配列ジャグ配列
サイズの固定行と列のサイズが固定各行のサイズが異なる
メモリの連続性メモリが連続して確保されるメモリが不連続になる可能性がある
アクセスの簡便さインデックスで直接アクセス可能各行のサイズを考慮する必要がある
使用例行列計算、固定サイズのデータ管理不規則なデータ構造の管理

多次元配列は、行と列のサイズが固定されている場合に適しており、ジャグ配列は、行ごとに異なるサイズのデータを扱う場合に便利です。

ジャグ配列の宣言と初期化

ジャグ配列を宣言し、初期化する方法を以下に示します。

int[][] jaggedArray = new int[2][]; // 2行のジャグ配列を宣言
jaggedArray[0] = new int[] { 1, 2 }; // 1行目を初期化
jaggedArray[1] = new int[] { 3, 4, 5 }; // 2行目を初期化
// ジャグ配列の要素を出力
for (int i = 0; i < jaggedArray.Length; i++)
{
    for (int j = 0; j < jaggedArray[i].Length; j++)
    {
        Console.Write(jaggedArray[i][j] + " "); // 要素を出力
    }
    Console.WriteLine(); // 行の終わりで改行
}

このコードでは、2行のジャグ配列を宣言し、各行を異なるサイズで初期化しています。

jaggedArray[i][j]を使用して要素にアクセスし、出力しています。

ジャグ配列は、柔軟なデータ構造を必要とする場合に非常に便利です。

多次元配列のメソッドとプロパティ

C#の多次元配列には、配列のサイズや次元数を取得するためのメソッドやプロパティがあります。

ここでは、GetLengthメソッドRankプロパティ、Lengthプロパティの使い方について解説します。

GetLengthメソッドの使い方

GetLengthメソッドは、指定した次元のサイズを取得するために使用されます。

以下の例では、2次元配列の行数と列数を取得しています。

int[,] twoDimensionalArray = { { 1, 2, 3 }, { 4, 5, 6 } }; // 2次元配列の初期化
int rows = twoDimensionalArray.GetLength(0); // 行数を取得
int columns = twoDimensionalArray.GetLength(1); // 列数を取得
Console.WriteLine($"行数: {rows}, 列数: {columns}"); // 出力: 行数: 2, 列数: 3

このコードでは、GetLength(0)で行数を、GetLength(1)で列数を取得し、出力しています。

Rankプロパティの使い方

Rankプロパティは、配列の次元数を取得するために使用されます。

以下の例では、2次元配列の次元数を取得しています。

int[,] twoDimensionalArray = { { 1, 2, 3 }, { 4, 5, 6 } }; // 2次元配列の初期化
int dimensions = twoDimensionalArray.Rank; // 次元数を取得
Console.WriteLine($"次元数: {dimensions}"); // 出力: 次元数: 2

このコードでは、Rankプロパティを使用して、配列の次元数を取得し、出力しています。

Lengthプロパティの使い方

Lengthプロパティは、配列の全要素数を取得するために使用されます。

以下の例では、2次元配列の全要素数を取得しています。

int[,] twoDimensionalArray = { { 1, 2, 3 }, { 4, 5, 6 } }; // 2次元配列の初期化
int totalElements = twoDimensionalArray.Length; // 全要素数を取得
Console.WriteLine($"全要素数: {totalElements}"); // 出力: 全要素数: 6

このコードでは、Lengthプロパティを使用して、配列の全要素数を取得し、出力しています。

これらのメソッドやプロパティを活用することで、多次元配列のサイズや次元数を簡単に取得し、効率的にデータを管理することができます。

多次元配列のコピーと操作

多次元配列を扱う際、配列のコピーや部分コピーは非常に重要な操作です。

ここでは、Array.CopyメソッドArray.Cloneメソッドを使った配列のコピー方法、そして配列の部分コピーについて解説します。

Array.Copyを使った配列のコピー

Array.Copyメソッドを使用すると、元の配列から指定した範囲の要素を新しい配列にコピーすることができます。

以下の例では、2次元配列の一部をコピーしています。

int[,] originalArray = { { 1, 2, 3 }, { 4, 5, 6 } }; // 元の配列
int[,] copiedArray = new int[2, 2]; // コピー先の配列
// 元の配列の一部をコピー
Array.Copy(originalArray, 0, copiedArray, 0, 2); // 0行目から2要素をコピー
// コピー結果を出力
for (int i = 0; i < copiedArray.GetLength(0); i++)
{
    for (int j = 0; j < copiedArray.GetLength(1); j++)
    {
        Console.Write(copiedArray[i, j] + " "); // 要素を出力
    }
    Console.WriteLine(); // 行の終わりで改行
}

このコードでは、Array.Copyを使って元の配列の最初の2要素を新しい配列にコピーしています。

Array.Cloneを使った配列のコピー

Array.Cloneメソッドを使用すると、配列全体を浅いコピーとして新しい配列にコピーすることができます。

以下の例では、2次元配列をコピーしています。

int[,] originalArray = { { 1, 2, 3 }, { 4, 5, 6 } }; // 元の配列
int[,] clonedArray = (int[,])originalArray.Clone(); // 配列全体をコピー
// コピー結果を出力
for (int i = 0; i < clonedArray.GetLength(0); i++)
{
    for (int j = 0; j < clonedArray.GetLength(1); j++)
    {
        Console.Write(clonedArray[i, j] + " "); // 要素を出力
    }
    Console.WriteLine(); // 行の終わりで改行
}

このコードでは、Array.Cloneを使って元の配列を完全にコピーし、新しい配列に格納しています。

配列の部分コピー

配列の一部をコピーする場合、Array.Copyメソッドを使うことが一般的ですが、特定の範囲を指定してコピーすることも可能です。

以下の例では、2次元配列の特定の部分をコピーしています。

int[,] originalArray = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; // 元の配列
int[,] partialCopiedArray = new int[2, 2]; // 部分コピー先の配列
// 元の配列の一部をコピー
for (int i = 0; i < 2; i++)
{
    for (int j = 0; j < 2; j++)
    {
        partialCopiedArray[i, j] = originalArray[i + 1, j + 1]; // 1行1列目から2x2の部分をコピー
    }
}
// コピー結果を出力
for (int i = 0; i < partialCopiedArray.GetLength(0); i++)
{
    for (int j = 0; j < partialCopiedArray.GetLength(1); j++)
    {
        Console.Write(partialCopiedArray[i, j] + " "); // 要素を出力
    }
    Console.WriteLine(); // 行の終わりで改行
}

このコードでは、元の配列の1行1列目から始まる2×2の部分を新しい配列にコピーしています。

これにより、特定の範囲のデータを効率的に管理できます。

まとめ

この記事では、C#における多次元配列の基本的な使い方や、さまざまな操作方法について詳しく解説しました。

多次元配列は、行列の計算や画像データの管理、ゲームのマップデータの管理など、幅広い用途で活用される重要なデータ構造です。

これを機に、実際のプログラミングにおいて多次元配列を積極的に活用し、より効率的なデータ管理を目指してみてください。

関連記事

Back to top button