参考:http://wiki.unity3d.com/index.php?title=Which_Kind_Of_Array_Or_Collection_Should_I_Use%3F
Unityの広義の配列―コレクション―はいくつか種類がある。それぞれ宣言や代入、値の取出しの記述が異なる。また、自由度が高い反面、使わないほうがよいものもある。
1)ビルトイン配列(Built-in Array)
もっとも基本的な配列で、もっとも高速。ただし宣言時に要素数を指定する必要がある。が、宣言後にリサイズは可能。(System.Array.Resize(ref myArray, size))で行う。)
C#での宣言、代入、リサイズは次のように行う。ただし、多次元のビルトイン配列はリサイズできない。
TheType myArray = new TheType[lengthOfArray];
int[] myNumbers = new int[10];
GameObject[] enemies = new GameObject[16];
int howBig = myArray.Length;
myArray[i] = newValue;
TheType thisValue = myArray[i];
System.Array.Resize(ref myArray, size);
string[] weapons = new string[] { "Sword", "Knife", "Gun" };
float[] alphas = new float[] { 1.0f };
2)Javascript配列(Javascript Array)
標準的な.netクラスにはない、Unity独自の配列。ただし名前通り、javascript型スクリプトでのみつかえ、C#型では使えない。
このため、サイズ変更可能、要素の型を宣言する必要がないなど柔軟性が高いが、反面、性能的にはもっとも遅い。
Javascript Arrayは基本的にはArrayListにラッパーをかけたものとみなせ、同様のことはObjectリストで実現できる。しかも速い。Javascript Arrayは「過去の遺産」と考えた方がよさそう。
3)アレイリスト(ArrayList)
Javascript Array以上に柔軟性がある(たとえば要素数を変更できるなど)が、性能上は遅い(*)。またArrayList自体には型はなく、任意の型を要素として持つことができる。型の混在も可能。
ただし、Generic Listの登場によりArrayListの存在意義はなくなったといわれる。旧式のコードとの互換性上のものと考えた方がよさそう。
(*)性能面のハンデの多くは宣言時に要素数を宣言しないため、という報告もある。つまり、ArrayListでも要素数を固定すれば、速度は改善するらしい。
ArrayList myArrayList = new ArrayList();
myArrayList.Add(anItem);
myArrayList[i] = newValue;
TheType thisItem = (TheType) myArray[i];
myArray.RemoveAt(i);
var howBig = myArray.Count;
4)ハッシュテーブル(Hashtable)
'key-value'方式で要素を参照する配列。
key, valueともにどんな型でもよい(untype)。型の混在も可能。(keyは通常はString型であることがおおいが。)このため、Hashtableから要素を取り出す際は、ユーザがCastしてやる必要がある。
ただし、ArrayListよりもGeneric Listが良いのと同じように、近年は、HashtableよりDictionaryを使う方が良い。
Hashtable myHashtable = new Hashtable();
myHashtable[anyKey] = newValue;
ValueType thisValue = (ValueType)myHashtable[theKey];
int howBig = myHashtable.Count;
myHashtable.Remove(theKey);
5) ジェネリック・リスト(Generic List)
Generic Listは、Listとも呼ばれる。要素数可変、要素の追加・削除ができる点ではJavascript, ArrayListと同等の柔軟性がある。違いは、定義時に型を指定する点。宣言した型の要素しか保持できないため
という利点がある。
つまり、特定の型のみ扱うことがわかっている場合は、ArrayListよりGeneric Listを使う方が良い。
using System.Collections.Generic;
List<Type> myList = new List<Type>();
List<int> someNumbers = new List<int>();
List<GameObject> enemies = new List<GameObject>();
myList.Add(theItem);
myList[i] = newItem;
Type thisItem = List[i];
myList.RemoveAt(i);
6) ジェネリック・ディクショナリー(Generic Dictionary)
HashtableのGneric List版。宣言時にkey, valueの型を指定する。このため、Gneric Listと同じ利点が得られる。
using System.Collections.Generic;
Dictionary<KeyType,ValueType> myDictionary = new Dictionary<KeyType,ValueType>();
Dictionary<string,Person> myContacts = new Dictionary<string,Person>();
myDictionary[anyKey] = newValue;
ValueType thisValue = myDictionary[theKey];
int howBig = myDictionary.Count;
myDictionary.Remove(theKey);
7) 2次元配列(2D Array)
以上はすべて1次元の配列について述べてきた。Unityでは2次元以上の配列を使うこともできる。以下は2次元配列についてのべるが、3次元、4次元…といった多次元配列を扱うこともできる。
「一般の」2次元配列の宣言では、外側・内側の2要素の要素数を指定する。
string[,] myArray = new string[16,4];
Tile[,] map = new Tile[32,32];
myArray[x,y] = newValue;
ValueType thisValue = myArray[x,y];
int width = myArray.GetLength(0);
int length = myArray.GetLength(1);
一方「ジャグ(jagged)」2次元配列では、(内側の)要素の数がそろっていなくても良い。
var myJaggedArray = [ [1, 2, 3], [4, 5], [6, 7, 8, 9, 10] ];
myArray[x][y] = newValue;
ValueType thisValue = myArray[x][y];
ちなみに、「ビルトイン配列(たとえば、GameObject[])を要素にもつジェネリック・リスト」を作るには次のように書く。
GameObject[] go1;
GameObject[] go2;
GameObject[] go3;
List<GameObject[]> gos = new List<GameObject[]>{go1,go2,go3};
以上、Unityで扱われる広義の配列について述べた。利用指針は次のようになるだろう。
・大きさがわかっているケースは、ビルトイン配列を使う。メモリ効率も速度ももっともよい。
・ArrayListのかわりにGneric Listを、Hashtableの代わりにGeneric Dictionaryを使う。
・Javascript Arrayは使わない。
要するに、型のキャストを避けるべき。
開発時はArrayListやHashtableを使ってもよいが、リリース時はGnericに変換するとよいだろう。