今回はC#の多次元配列とジャグ配列を使用してみます。
以前配列については変数についての記事に書きましたが。
多次元配列やジャグ配列については記載していなかったので、改めて勉強していくことにします。
多次元配列
多次元配列とはいわゆる行列を表現したデータ構造ですね、行列と言われると数学的に考えて難しくなりそうですが、
お店の行列だったり、学校の朝礼時に学年、クラス毎に並ぶ行列を思い浮かべて頂くとわかりやすいですね。
そういったデータを扱う時に使うのが多次元配列になります。
多次元配列の宣言
多次元配列を宣言する時はデータの型と[]を使用します。[]の中には,を入れ配列の次元を変更する事が出来ます。
1 2 3 4 | int[,] intValues; string[, ,] stringValues; |
↑の例ではint型の2次元配列intValuesとstring型の3次元配列stringValuesを宣言しています。
多次元配列の要素の確保
多次元配列は宣言しただけではどれだけのデータを格納できるかわからないので要素の確保をする必要があります。
1 2 3 4 | intValues = new int[4, 3]; stringValues = new string[1, 2, 3]; |
↑の用に行列の要素数の指定を行います。intValuesは2次元なので4行3列の配列ですね、3次元以降はどう言ったらいいのかわかりませんが1行2行3列?ですね。
配列変数の宣言と同時に配列の要素の確保も出来るので、
1 2 3 4 | int[,] intValues2 = new int[4, 3]; string[, ,] stringValues2 = new string[1, 2, 3]; |
とする事も出来ます。
多次元配列のデータの初期化
多次元配列データに初期値を設定する事も出来ます。
1 2 3 | int[,] intValues = new int[,] {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}}; |
↑の例では、intValues[0, 0]に0、intValues[0, 1]に1・・・、intValues[2, 2]に8と設定され、3行3列の2次元配列となります。
行の切り替わりにあたる部分を{}で分けます。
多次元配列へのデータの格納
多次元配列にデータを入れる場合は配列と同じように要素の番号を指定してデータを格納します。
初期化の項目でやりましたが、配列の要素番号を指定し入れたいデータを代入するだけです。
1 2 3 4 5 6 7 8 9 10 11 | stringValues = new string[2, 3]; stringValues [0, 0] = "abc"; stringValues [0, 1] = "def"; stringValues [0, 2] = "ghi"; stringValues [1, 0] = "jkl"; stringValues [1, 1] = "mno"; stringValues [1, 2] = "pqr"; |
配列の複数版なので特別難しい事はありませんね。
多次元配列のデータの取得
多次元配列のデータの取得も格納と同じように要素番号を指定するだけです。
1 2 3 | Debug.Log (intValues [0, 0]); |
↑の例ではintValuesの0行0列に格納されているデータをコンソールに出力します。
多次元配列のサンプル
多次元配列の使い方がわかったので簡単なサンプルを作ってみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | using UnityEngine; using System.Collections; public class ArrayTest : MonoBehaviour { private int[,] intValues; private string[,] stringValues; // Use this for initialization void Start () { // 配列の要素数の確保 intValues = new int[,] { {0, 1, 2}, {3, 4, 5}, {6, 7, 8} }; // 配列の要素を個別に出力してみる Debug.Log (intValues [0, 0] + ":" + intValues [0, 2]); // 多次元配列の要素を全出力 foreach (var intValue in intValues) { Debug.Log (intValue); } // 配列の要素数の確保 stringValues = new string[2, 3]; // 要素を個別に設定 stringValues [0, 0] = "abc"; stringValues [0, 1] = "def"; stringValues [0, 2] = "ghi"; stringValues [1, 0] = "jkl"; stringValues [1, 1] = "mno"; stringValues [1, 2] = "pqr"; // 配列要素の出力 foreach (var stringValue in stringValues) { Debug.Log (stringValue); } } } |
多次元配列の要素を全部取得したい時はfor文やforeach文を使うと簡単に取得出来ます。
ジャグ配列
ジャグ配列も多次元配列と同じようなものですが、こちらの場合は行列ではなく配列の中に配列を入れるという構造になっています。
ジャグ配列の宣言
ジャグ配列の宣言は多次元配列と違い配列の数だけ[]を書きます。
1 2 3 4 | private int[][] intValues; private string[][] stringValues; |
↑の例ではintValues、stringValues共に配列の中に一つの配列が格納されます。
ジャグ配列のデータの確保
ジャグ配列のデータの確保は最初の要素数だけ指定します。
1 2 3 | intValues = new int[3][]; |
これで3つの要素が確保されますが、その3つの要素の中にさらに配列があるので、その要素である配列のデータの確保も必要になります。
1 2 3 4 5 | intValues [0] = new int[2]; intValues [1] = new int[3]; intValues [2] = new int[2]; |
↑のように各要素の配列のデータの確保が必要になります。
その為、要素に入れる配列の数が増えれば増えるだけ複雑化します。
1 2 3 4 5 6 7 8 9 10 11 | int[][][] intValues2 = new int[2][][]; intValues2 [0] = new int[2][]; intValues2 [1] = new int[2][]; intValues2 [0] [0] = new int[1]; intValues2 [0] [1] = new int[1]; intValues2 [0] [0] [0] = 0; |
↑のように段階的に要素の確保をする必要が出てきますね。
ジャグ配列のデータの初期化
ジャグ配列もデータの確保と初期化が出来ます。
1 2 3 | stringValues = new string[][] { new string[] { "abc" }, new string[] { "def", "ghi" }, new string[] { "jkl" } }; |
ジャグ配列は配列に配列が入るので、入れるデータは配列データになります。
ジャグ配列へのデータの格納
ジャグ配列へのデータの格納も多次元配列と同じように出来ます。
1 2 3 4 5 6 7 8 9 10 | string[][] stringValues2 = new string[2][]; stringValues2 [0] = new string[1]; stringValues2 [1] = new string[2]; stringValues2 [0] [0] = "a"; stringValues2 [1] [0] = "b"; stringValues2 [1] [1] = "c"; |
ジャグ配列のデータの取得
ジャグ配列のデータの取得も多次元配列と同じようにする事が出来ます。
1 2 3 | Debug.Log(stringValues2[0][0]); |
↑の例ではstringValues2の0番目の配列の0番目の要素がコンソールに表示されます。
ジャグ配列の使用サンプル
ジャグ配列の使用方法がわかったところでサンプルを作成してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | using UnityEngine; using System.Collections; public class JaggedArray : MonoBehaviour { private int[][] intValues; private string[][] stringValues; // Use this for initialization void Start () { intValues = new int[3][]; intValues [0] = new int[2]; intValues [1] = new int[3]; intValues [2] = new int[2]; intValues [0] [0] = 0; intValues [0] [1] = 1; intValues [1] [0] = 2; intValues [1] [1] = 3; intValues [1] [2] = 4; intValues [2] [0] = 5; intValues [2] [1] = 6; foreach (var lines in intValues) { foreach (var line in lines) { Debug.Log (line); } } int[][][] intValues2 = new int[2][][]; intValues2 [0] = new int[2][]; intValues2 [1] = new int[2][]; intValues2 [0] [0] = new int[1]; intValues2 [0] [1] = new int[1]; intValues2 [0] [0] [0] = 0; stringValues = new string[][] { new string[] { "abc" }, new string[] { "def", "ghi" }, new string[] { "jkl" } }; for (int i = 0; i < stringValues.Length; i++) { foreach (var stringValue in stringValues[i]) { Debug.Log (i + ":" + stringValue); } } string[][] stringValues2 = new string[2][]; stringValues2 [0] = new string[1]; stringValues2 [1] = new string[2]; stringValues2 [0] [0] = "a"; stringValues2 [1] [0] = "b"; stringValues2 [1] [1] = "c"; for (int i = 0; i < stringValues2.Length; i++) { foreach (var stringValue2 in stringValues2[i]) { Debug.Log (i + ":" + stringValue2); } } } } |
ジャグ配列の場合は配列の中の配列を取得する為、場合によっては繰り返し文の中で繰り返し文を使って要素のデータを取得します。
終わりに
Unity関連の記事で多次元配列やジャグ配列は使っていませんが、場合によっては使うと便利な事も出てきますね。
キャラクターのレベルに応じて複数のアイテムからランダムに1つだけアイテムが得られるような機能を作成したい時は、レベル毎に取得出来るアイテムを格納しておき、そこから選ぶようにするといいかもしれません。
今回、多次元配列を勉強する事でC#の多次元配列とジャグ配列の2つがある事がわかりました。
わたくしが今まで使ってきたプログラミング言語の配列はジャグ配列に近いような気がします。
でも、C#の多次元配列の方が構造がわかりやすいかもしれませんね、でも3次元以降になるとジャグ配列の方がわかりやすいような気もしますが・・・(-_-)
多次元配列とジャグ配列を混在させる事も出来るみたいですが、うーむこんがらがりそう・・・・(^_^;)