コレクション
複数のデータをひとまとめにして管理できる変数で代表的なものは3つ
・配列(要素数が固定されて扱われる代表的なデータ構造)
・リスト(要素の追加、削除、挿入ができるデータ構造)
・ディクショナリ(要素に "キー" と "値" がセットで格納させるデータ構造)
今回は配列(Array)について学習していきます。
配列
配列は同じ型を持つ値を一つの変数内に連続して格納できます。
配列の宣言時に要素数が決まり、以降は要素の数を変更することはできません。各要素の値の更新はできます。
要素を呼び出すときはインデックスと呼ばれる0から始まる連番で要素番号を指定して呼び出します。
配列の宣言について
配列の構文は次のようになります。
型名[] 配列名 = new 型名[] {要素1, 要素2, 要素3, ... };
実際にコードを書を書いてみます。部分的に省略した書き方もでき、次のようになります。
//整数
int[] a = {1,2,3,4,5};
int[] b = new int[]{1,2,3,4,5};
int[] c = new int[5]{1,2,3,4,5};
どの記述方法も整数型の配列に初期値を設定している書き方で、どれも同じ扱いができます。3つ目の書き方は、一目で要素数が分かるので、コードの可読性が高くなります。プロジェクト内では混在させずに、どれか一つの書き方で統一した方がよさそうです。
他の型での宣言方法も同じです。
//文字列
string[] a = {"斎藤", "鈴木", "高橋", "田中", "伊藤"};
string[] b = new string[]{"斎藤", "鈴木", "高橋", "田中", "伊藤"};
string[] c = new string[5]{"斎藤", "鈴木", "高橋", "田中", "伊藤"};
//浮動小数
float[] a = { 1.0f, 3.4f, 5.2f, -3.5f, 8.2f };
float[] b = new float[] { 1.0f, 3.4f, 5.2f, -3.5f, 8.2f };
float[] c = new float[5] { 1.0f, 3.4f, 5.2f, -3.5f, 8.2f };
配列は要素の数を固定して使用する変数なので、宣言時に要素の数を指定する必要があります。
これまでは配列の宣言時に初期値も設定する記述でしたが、例えば初期値を設定しない場合に、次のような記述ができません。
int[] a;
int[] b = new int[];
上記2つの書き方は要素数が特定できないのでエラーとなります。
配列に初期値を設定しない時の変数の宣言は次のように記述します。
//初期値を設定しない配列の型の宣言
int[] b = new int[5];
初期値を設定しない場合は、要素数を指定するために大括弧に要素数を記述します。
この場合、初期値を設定しなくても要素数が "5" と指定されているのでOKです。
要素の呼び出し
配列の要素はインデックス番号を指定して呼び出します。配列の要素は0から順にインデックス番号が割り当てられています。
//要素の呼び出し
string[] names = new string[]{"斎藤", "鈴木", "高橋", "田中", "伊藤"};
Debug.Log(names[0]);
Debug.Log(names[3]);
インデックス番号は整数値なので、変数で指定することもできます。
//インデックス番号に変数を使用
string[] names = new string[]{"斎藤", "鈴木", "高橋", "田中", "伊藤"};
int number = 3;
Debug.Log(names[number]);
配列の要素数は簡単に取り出すことができます。
//配列の要素数を取得
string[] names = new string[] { "斎藤", "鈴木", "高橋", "田中", "伊藤" };
int num = names.Length;
Debug.Log(num);
for文と組み合わせて、配列の全ての要素に処理を加えるコードの書き方はよく使われます。
string[] names = new string[] { "斎藤", "鈴木", "高橋", "田中", "伊藤" };
for (int i = 0; i < names.Length; i++)
{
Debug.Log($"{names[i]}さん、こにちは。");
}
一次元配列
これまで記述した、上記のサンプルコードはどれも一次元配列です。1行に要素が連続で格納されているイメージです。
ここで既定値についても少し触れておきます。型の宣言時に初期値を設定しない場合の要素の値についてです。
int[] c = new int[3];
c[1] = 6;
for (int i = 0; i < c.Length; i++)
{
Debug.Log(c[i]);
}
整数型で要素数が3の配列変数を宣言して、一つの要素には値を代入しました。このコードを実行すると、初期値を設定しなかった要素の出力値は0になっていることが分かります。
配列の要素には既定値があり、数値型で初期値が設定されない場合の既定値は0です。
他の型にも既定値があり、それぞれ次のように設定されています。
・数値型(int,float)の既定値:0
・論理型(bool)の既定値:false
・参照型(string)の既定値:null
二次元配列
2次元配列は表形式でデータを管理します。スプレッドシートのセルが要素として扱われるイメージです。宣言の書き方が2つありましたので紹介します。
まず1つ目の宣言方法です。
//宣言時に初期値を設定
int[,] a = new int[,] { {1, 2, 3 },{4, 5, 6 },{7, 8, 9 } };
//配列の宣言だけ行い、後から値を代入
int[,] b = new int[3,3];
int n = 0;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
b[i, j] = n;
Debug.Log(b[i, j]);
n++;
}
}
こちらは比較的新しい2次元配列の宣言の書き方のようです。データが行と列で格納された構造になっています。
C#では使用できますが、他のプログラム言語と比較したときにコードの書き方の互換性がありません。
2つ目の書き方を見てみます。
//1次元配列の変数
int[] a = new int[] { 1, 2, 3 };
int[] b = new int[] { 4, 5 };
int[] c = new int[] { 6, 7, 8, 9, 10 };
//ジャグ配列の宣言
int[][] array = new int[3][];
array[0] = a;
array[1] = b;
array[2] = c;
Debug.Log(array[2][3]);
2つ目は配列の中に配列を格納した構造になっています。ジャグ配列とも呼ばれます。
ジャグ配列では、中に入っている配列がそれぞれ異なる要素数でも問題ありません。
少しだけ、2次元配列を使った簡単な表計算をしてみます。5人のプレーヤーが3回の競技を行った時の点数を記録したデータがあるとします。このデータから個人の平均スコアを計算してみます。
string[] names = new string[] { "斎藤", "鈴木", "高橋", "田中", "伊藤" };
int[] score1 = new int[] {79, 64, 68, 85, 53 };
int[] score2 = new int[] {63, 48, 84, 55, 74 };
int[] score3 = new int[] {76, 85, 59, 44, 62 };
//一次元配列のデータを2次元配列に代入して一つの変数にまとめる
int[][] scores = new int[][] {score1, score2, score3 };
//汎用的に使えるように、行数と列数を調べる
int row = scores.GetLength(0); //行の要素数を調べる
int col = scores[0].GetLength(0); //列の要素数を調べる
//プレーヤー個人のスコア平均の計算
for (int i = 0; i < col; i++)
{
float sum = 0.0f; //合計値を計算するために初期化
for (int j = 0; j < row; j++)
{
sum += scores[j][i];
}
float scoreAverage = sum / row; //スコアの平均計算
Debug.Log($"{names[i]}さんのスコア平均{scoreAverage}");
}
スプレッドシートで計算したときの結果を比較用として記載します。
まずは簡単なコードを見ながら配列について勉強してみました。
追記情報
2024/07/08(配列長さの取得について)
配列の要素数の取得について、説明ではさらっと記述していましたので、整理して記述します。
説明では配列に設定した要素の数をそのまま「要素数」と記述していますが、「配列長さ」と表現する方が一般的な表現のようです。
配列長さを取得するメソッド
・「.Length」:配列要素全体の長さを取得
・「.GetLength( )」:次元を指定して長さを取得
コードを書いてみます。
//配列長さだけを指定した配列の宣言
int[] a = new int[3];
int[,] b = new int[4, 5];
int[,,] c = new int[3, 2, 4];
//1次元配列の配列長さ取得
Debug.Log(a.Length);
//2次元配列の配列長さ取得
Debug.Log(b.Length); //全体の配列長さ
Debug.Log(b.GetLength(0)); //1次元目の配列長さ
Debug.Log(b.GetLength(1)); //2次元目の配列長さ
//3次元配列の配列長さ取得
Debug.Log(c.Length); //全体の要素数
Debug.Log(c.GetLength(0)); //1次元目の配列長さ
Debug.Log(c.GetLength(2)); //3次元目の配列長さ
1次元配列では次元が1つなので全体の長さを取得する「.Length」メソッドが使われます。多次元配列でそれぞれの次元の長さを調べる場合は「.GetLength( )」で次元を指定して長さを調べます。