今回はC#のListを勉強していきたいと思います。
一連の同じ型のデータを扱う時は、配列を使うのが便利ですが、配列の場合は使用する前に使用する要素の数を指定する必要があります。
Listの場合は要素数をあらかじめ指定する必要がなく追加、削除が行えますので、用途によってはこちらの方が使い勝手が良くなります。
例えば、アクションゲーム等で主人公の半径5m以内にいる敵のゲームオブジェクトを取得したいといった時、
配列を使った場合主人公の5m以内に何人の敵が入るかわからない為、ある程度大きめの要素を確保しておいて要素数を越えないようにしておく必要がありますし、範囲内に敵が入ったら配列の空の要素を探し、そこに新しく入った敵を入れる。
敵が範囲外に出たら要素からその敵を探し削除するという作業が必要になります。
あらかじめ配列の要素が決まっている為、要素全てに敵が入るわけでもなく虫食いの状態になります。
リストを使った場合は敵の追加、削除を簡単に行えますし、要素数はその都度変わっていきます。
空の要素の事を考えなくて済むので楽ですね(^_^)v
Listを使ってみる
今回使用するListはジェネリック版のリストを使っていきます。
ジェネリックについてはこちらで解説されています。
リストに型の制限を加えて、他の型の値が入らないように出来るって感じですかね。
Listの宣言
まずはリストの宣言をしてみます。
1 2 3 4 | List<型> list = new List<型>(); var list2 = new List<型>(); |
↑のように型の部分を指定してリストの宣言が出来ます。
右辺は型が決まっているのでvarも使用出来ます。
実際に型を指定して宣言すると、
1 2 3 4 | List<int> intList = new List<int>(); var stringList = new List<string>(); |
最初のリストはint型の値を入れるリストで、2番目のリストはstring型の値を入れるリストとなります。
UnityのGameObject型を入れるリストを作る場合は
1 2 3 | var gameObjectList = new List<GameObject> (); |
等と型の部分をGameObjectに変更するだけです。
リストの初期化
リストも配列と同じような感じで初期値を設定する事が出来ます。
1 2 3 | List<string> stringList = new List<string>{ "test1", "test2" }; |
{}の中に要素を指定します。
リストに要素を追加する
リストに値を追加するには、Add、AddRange、Insert、InsertRangeがあります。
サンプルで使う為、あらかじめstringListとaddList変数を宣言しておきます。
1 2 3 4 5 6 | // string型を格納するリストの作成 List<string> stringList = new List<string>{ "test1", "test2" }; // 後で追加するリスト List<string> addList = new List<string>{ "test4", "test5" }; |
Add
Addメソッドは要素の最後に値を追加する事が出来ます。
1 2 3 | stringList.Add ("test3"); |
引数には追加する要素を書きます。
stringListの最後にtest3という文字列の要素が追加されます。
stringListは test1 test2 test3 という順番で格納されることになります。
AddRange
AddRangeメソッドはリストにコレクションクラス(配列やリスト等の複数のデータを扱うクラス)を追加する事が出来ます。
1 2 3 | stringList.AddRange (addList); |
↑の例ではstringListの最後にaddListを追加します。
stringListは test1 test2 test4 test5 となります。
Insert
Insertメソッドは指定した要素番号の位置に要素を追加します。
1 2 3 | stringList.Insert (0, "insertString"); |
↑の例では0番目の要素にinsertStringを追加します。
stringListは insertString test1 test2 となります。
InsertRange
InsertRangeメソッドは指定した要素番号の位置にコレクションクラスを追加します。
1 2 3 | stringList.InsertRange (1, addList); |
↑の例では1番目にaddListを追加します。
結果stringListは test1 test4 test5 test2 となります。
リストから要素を削除する
リストから要素を削除する時は、Remove、RemoveAt、RemoveAll、RemoveRange、Clearを使用します。
Remove
Removeメソッドを使うと、リストの中から該当する最初に見つかった要素を削除します。
1 2 3 | stringList.Remove ("test1"); |
これを実行するとstringListは test2 になります。
RemoveAt
RemoveAtメソッドを使うと、指定した要素番号の要素を削除します。
1 2 3 | stringList.RemoveAt (0); |
これを実行するとstringListは test2 となります。
RemoveAll
RemoveAllメソッドを使うと、リスト中から該当する要素が全て削除されます。
1 2 3 | stringList.RemoveAll (x => x.Contains ("test")); |
RemoveAllの引数にはPredicateデリゲートを指定します。
Pridicateデリゲートとはそのオブジェクトが条件を満たしているかどうか確認するメソッドらしいですが、よくわかりませんね・・・(^_^;)
デリゲートはメソッド呼び出しの引数として渡す事が出来るので、メソッド自体を引数として渡している感じです。
上記の例ではラムダ式を使っていますが、ラムダ式はまだ記事を書いていないのでここでは省略しますが、
やっている事はリストの要素中にtestという文字列が含まれていればリストから削除するということです。
RemoveRange
RemoveRangeメソッドは第1引数で指定した要素番号から第2引数で指定した数分だけ要素を削除します。
1 2 3 | stringList.RemoveRange (0, 1); |
↑の例では、0番目の要素から1つ削除します。
stringListは test2 となります。
Clear
Clearメソッドを使用するとリストに登録されている要素が全て削除されます。
1 2 3 | stringList.Clear(); |
↑の処理を行うとリストが空になります。
要素の取得方法
要素を操作する事は出来ましたが、取得する方法も必要になります。
配列と同じようにリスト名の後に[]を付けて要素番号を指定します。
1 2 3 | Debug.Log (stringList [0]); |
↑の例では test1 が表示されます。
リストの中から条件にあったものを取得する
リストの要素の中から指定した条件に合致した要素を取得する方法も必要ですね。
BinarySearchを使う
BinarySearchメソッドを使うと条件に合致した要素の要素番号を取得出来ます。
1 2 3 | Debug.Log(stringList.BinarySearch ("test1")); |
↑の例では0がコンソールに表示されます。
IndexOf
IndexOfメソッドを使うと、条件にあった最初の要素の要素番号を取得する事が出来ます。
要素が見つからなかった場合は-1が返ります。
1 2 3 | stringList.IndexOf ("test"); |
↑の例では-1が取得出来ます。
LastIndexOf
LastIndexOfは条件にあった最後の要素の要素番号を取得する事が出来ます。
1 2 3 | stringList.LastIndexOf ("test"); |
↑の例では-1が取得出来ます(要素が見つからない為)。
Find
Findメソッドを使用すると引数でPredicateデリゲートを指定し、その条件に合致した最初の要素を取得出来ます。
1 2 3 | stringList.Find (x => x.Contains ("test")); |
↑の例ではtest1が取得出来ます。
FindIndex
FindIndexメソッドを使用すると引数でPredicateデリゲートを指定し、その条件に合致した最初の要素の要素番号を取得出来ます。
1 2 3 | stringList.FindIndex (x => x.Contains ("test")); |
↑の例では0が取得出来ます。
FindLast
FindLastメソッドは引数でPredicateデリゲートを指定し、条件に合致した最後の要素を取得します。
1 2 3 | stringList.FindLast (x => x.Contains ("test")); |
↑の例ではtest2が取得出来ます。
FindLastIndex
FindLastIndexメソッドは引数でPredicateデリゲートを指定し、条件に合致した最後の要素の要素番号を取得します。
1 2 3 | stringList.FindLastIndex (x => x.Contains ("test")); |
↑の例では1が取得出来ます。
FindAll
FindAllメソッドは引数でPredicateデリゲートを指定し、条件に合致した要素のリストを取得する事が出来ます。
1 2 3 | List<string> newList = stringList.FindAll (x => x.Contains ("test")); |
↑の例では test1 test2 という要素を持つリストが返され、newListに入ります。
リスト中に条件にあった要素があるかどうか
Contains
Containsメソッドは引数で指定した要素があればtrue、なければfalseを返します。
1 2 3 | stringList.Contains ("test1"); |
↑の例ではtrueが返ります。
Exists
Existsメソッドは引数にPredicateデリゲートを指定し、その条件に合致しているかどうかを調べます。
1 2 3 | stringList.Exists (x => x.Length >= 5); |
↑の例ではtrueが返ります。
Containsとの違いは引数にPredicateデリゲートを指定するところです。
リストの要素数を調べる
リストの要素数を調べるにはCountメソッドを使用します。
1 2 3 | stringList.Count |
↑の例では2が返ってきます。
リストを配列に変換する
リストを配列に変換したい時はToArrayメソッドを使用します。
1 2 3 | string[] newArray = stringList.ToArray () |
↑ではstringListリストを配列に変換しnewArrayに入れています。
リストの要素を並べ替える
リストの要素を並べ替えるにはSortメソッド、Reverseメソッドを使用します。
Sort
Sortメソッドは引数に何も指定しなければデータを昇順に並べ替えます。
1 2 3 | stringList.Sort (); |
↑を実行するとリストは test1 test2 の順番になります。
Sortの引数に比較メソッドを指定し、並び順を変更する事も出来ます。
まずは以下のような比較メソッドを用意します。
1 2 3 4 5 6 | // 要素の文字列の長さで降順にする private static int Compare(string x, string y) { return y.Length - x.Length; } |
↑の場合は文字列の長さで並び順を変えますが、第2引数側から第1引数側を引いている為、文字列が長い順に並び変えます。
戻り値で0より小さければそちらが前、0なら同じ、0より大きければ後ろになります。
SortでこのCompareメソッドを指定すると
1 2 3 | stringList.Sort (Compare); |
となり、stringListの並び順は test2 test1 となります。
Sortに関しては
こちらに詳しく載っています。
Reverse
Reverseメソッドを使うとリストを降順に並べ替える事が出来ます。
1 2 3 | stringList.Reverse (); |
↑を実行するとstringListは test2 test1 となります。
最後に確認する
最後にこれまでの処理を色々詰め込んだサンプルを作成したので、実行して確認してみます。
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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Xml.Linq; public class Learn4_1 : MonoBehaviour { // Use this for initialization void Start () { // string型を格納するリストの作成 List<string> stringList = new List<string>{ "test1", "test2" }; // 後で追加するリスト List<string> addList = new List<string>{ "test4", "test5" }; // リストの要素を出力 Debug.Log ("1番目の要素 " + stringList [0]); Debug.Log ("2番目の要素 " + stringList [1]); // リストに要素を追加 stringList.Add ("test3"); Debug.Log ("3番目の要素 " + stringList [2]); // リストにリストを追加 stringList.AddRange (addList); Debug.Log ("4番目の要素 " + stringList [3]); Debug.Log ("5番目の要素 " + stringList[4]); // バイナリーサーチで要素を検索しインデックス値を表示 Debug.Log("test3をバイナリーサーチしたインデックス値 " + stringList.BinarySearch ("test3")); // 要素数を表示 Debug.Log ("リストの要素数 " + stringList.Count); // 要素をクリアにする stringList.Clear (); // 指定した要素が存在するかどうか表示 Debug.Log("リストにtest1が含まれているか? " + stringList.Contains ("test1")); stringList.Add ("0123456789"); stringList.Add ("test"); // デリゲートで指定した要素が存在するかどうか Debug.Log("リストに文字列が11以上の要素が含まれているかどうか? " + stringList.Exists (x => x.Length >= 11)); stringList.Add ("test2"); // 簡単な検索 Debug.Log("testが見つかった要素番号 " + stringList.IndexOf ("test")); Debug.Log("testが見つかった最後の要素番号 " + stringList.LastIndexOf ("test")); // デリゲートを使った検索 // 最初に合致した要素だけ表示 Debug.Log("リストから条件の合致する要素を探す " + stringList.Find (x => x.Contains ("test"))); Debug.Log ("リストから条件の合致する要素の要素番号 " + stringList.FindIndex (x => x.Contains ("test"))); // 最後に合致した要素だけ表示 Debug.Log ("合致した最後の要素 " + stringList.FindLast (x => x.Contains ("test"))); Debug.Log ("合致した最後の要素番号 " + stringList.FindLastIndex (x => x.Contains ("test"))); // 条件に合致する要素全てを取得 List<string> newList = stringList.FindAll (x => x.Contains ("test")); Debug.Log ("リストから条件の合致する全ての要素を探す " + newList[0] + " : " + newList[1]); // 指定した要素番号の位置に要素を追加 stringList.Insert (0, "insertString"); // 指定した要素番号の位置にリストを追加 stringList.InsertRange (1, addList); // testに合致する要素を削除 stringList.Remove ("test"); // 0番目の要素を削除 stringList.RemoveAt (0); // 要素を全削除 stringList.RemoveAll (x => x.Contains ("test")); stringList.AddRange (addList); // 指定した要素番号から指定した数分だけの要素を削除 stringList.RemoveRange (0, 1); // test5が表示される Debug.Log (stringList [0]); stringList.Add ("test"); // リストから配列を作成 string[] newArray = stringList.ToArray (); Debug.Log (newArray [0] + " : " + newArray [1]); stringList.Add ("testtest"); // ソートの効果を確認する為、一旦リストを表示 Debug.Log ("現リスト " + stringList [0] + " : " + stringList [1] + " : " + stringList[2]); stringList.Sort (); Debug.Log ("ソートしたリスト " + stringList [0] + " : " + stringList [1] + " : " + stringList[2]); // ソートの順序の仕方を変更 stringList.Sort (Compare); Debug.Log ("デリゲートを指定し、ソートしたリスト " + stringList [0] + " : " + stringList [1] + " : " + stringList[2]); stringList.Sort (); Debug.Log ("現リスト " + stringList [0] + " : " + stringList [1] + " : " + stringList[2]); stringList.Reverse (); Debug.Log ("Reverseを使って降順に並び変え " + stringList [0] + " : " + stringList [1] + " : " + stringList[2]); } // 要素の文字列の長さで降順にする private static int Compare(string x, string y) { return y.Length - x.Length; } } |
コメントも入れてあるので順に追ってみてください。
実行結果は
↑のようになります。
実行結果が多すぎて切り取れなかった為、最初の1番目の要素、2番目の要素部分はありません。
終わりに
Listの全部ではないですが、細かいメソッドまで見ていったのでだいぶ長い記事になりました。
ここまで細かくメソッドを追うつもりはなかったんですが、自分の確認用に色々載せておきました・・・・(^_^;)
すぐに忘れてしまいますので・・・・(T_T)