Flash CS3 ドキュメンテーション |
|||
| ActionScript 3.0 のプログラミング > 配列の操作 > インデックス配列 | |||
インデックス配列では、格納した一連の値に、符号なし整数値によるインデックスを指定してアクセスします。配列内の先頭の要素は常にインデックス 0 で示され、それに続く個々の要素は順に 1 ずつ大きい数のインデックスで示されます。次のコードに示すように、インデックス配列を作成するには Array クラスのコンストラクタを呼び出すか、配列リテラルを使用して配列を初期化します。
// Array コンストラクタを使用する
var myArray:Array = new Array();
myArray.push("one");
myArray.push("two");
myArray.push("three");
trace(myArray); // 出力: one,two,three
// Array リテラルを使用する
var myArray:Array = ["one", "two", "three"];
trace(myArray); // 出力: one,two,three
また、Array クラスのプロパティとメソッドを使用すると、インデックス配列に変更を加えることができます。それらのプロパティとメソッドはほとんどがインデックス配列専用であり、結合配列には使用できません。
インデックス配列のインデックスに使用する数値は、符号なし 32 ビット整数です。インデックス配列の最大サイズは 232- 1 (4,294,967,295) です。この最大サイズより大きい配列を作成しようとすると、ランタイムエラーが発生します。
配列の要素には、あらゆるデータ型の値を格納できます。ActionScript 3.0 では "型付き配列" の概念がサポートされていないため、配列内のすべての要素が特定の同じデータ型を持つことを指定する方法はありません。
このセクションでは、Array クラスを使用してインデックス配列を作成および変更する方法について、まず配列の作成から順に説明します。配列に変更を加えるメソッドは、要素の挿入に関するもの、要素の削除に関するもの、配列のソートに関するものの 3 つのグループに大別されます。その他に、既存の配列を読み取り専用として扱うメソッドがあり、そのようなメソッドでは配列に対してクエリを実行するだけです。クエリ関連のメソッドは、既存の配列を変更することなく、新しく作成した配列を返します。このセクションの最後には、Array クラスの拡張に関する話題を取り上げます。
Array コンストラクタ関数には 3 つの使用方法があります。第 1 に、パラメータを指定せずに呼び出した場合、コンストラクタは空の配列を返します。Array クラスの length プロパティを使用すると、配列の要素が 1 つもないことを確認できます。たとえば次のコードは、Array コンストラクタを引数なしで呼び出しています。
var names:Array = new Array(); trace(names.length); // 出力 : 0
第 2 に、1 個の数値パラメータだけを指定した場合、Array コンストラクタではそのパラメータで指定された長さの配列を作成し、各要素の値を undefined に設定します。指定する引数は、0 ~ 4,294,967,295 の値を持つ符号なし整数である必要があります。たとえば次のコードは、1 個の数値引数を指定して Array コンストラクタを呼び出しています。
var names:Array = new Array(3); trace(names.length); // 出力 : 3 trace(names[0]); // 出力: undefined trace(names[1]); // 出力: undefined trace(names[2]); // 出力: undefined
第 3 に、パラメータとして要素リストを指定した場合、コンストラクタでは、各パラメータの値を個々の要素に設定した配列を作成します。次のコードでは、Array コンストラクタに対し 3 つの引数を指定しています。
var names:Array = new Array("John", "Jane", "David");
trace(names.length); // 出力 : 3
trace(names[0]); // 出力: John
trace(names[1]); // 出力: Jane
trace(names[2]); // 出力: David
また、配列リテラルまたはオブジェクトリテラルから配列を作成することもできます。配列リテラルは、次の例に示すように配列変数に直接割り当てることができます。
var names:Array = ["John", "Jane", "David"];
配列に要素を挿入する場合は、Array クラスにある --push()、--unshift()、--splice() の 3 つのメソッドを使用できます。push() メソッドでは、配列の末尾に 1 つまたは複数の要素を追加します。したがって、push() メソッドで挿入した最後の要素には最も大きいインデックス番号が付きます。unshift() メソッドでは、配列の先頭に 1 つまたは複数の要素を挿入します。したがって、挿入した要素には必ずインデックス番号 0 が付きます。splice() メソッドでは、配列内の指定されたインデックスに任意の数の要素を挿入します。
これら 3 つのメソッドについて使用例を次に示します。この例では、planets という名前の配列を作成し、惑星の名前を太陽から近い順に並ぶように格納します。まず push() メソッドを呼び出し、最初の要素として Mars を挿入します。次に、配列の先頭に位置する要素 Mercury を unshift() メソッドで挿入します。最後に splice() メソッドで、Venus および Earth を Mercury より後、Mars より前に挿入します。splice() の第 1 パラメータとして渡している整数 1 は、挿入先をインデックス 1 の場所にするという指定です。また、splice() 第 2 パラメータの整数 0 は、既存の要素を 1 つも削除しないという指定です。さらに、splice() の第 3 および第 4 パラメータで指定している Venus と Earth は挿入する要素のリストです。
var planets:Array = new Array();
planets.push("Mars"); // 配列の内容: Mars
planets.unshift("Mercury"); // 配列の内容: Mercury,Mars
planets.splice(1, 0, "Venus", "Earth");
trace(planets); // 配列の内容: Mercury,Venus,Earth,Mars
push() および unshift() メソッドはいずれも、変更後の配列の長さを示す符号なし整数値を返します。splice() は要素の挿入に使用した場合、空の配列を返します。これは奇異な動作のようにも見えますが、splice() メソッドの幅広い用途を考えると理にかなっています。splice() メソッドは配列に要素を挿入する場合だけでなく、配列から要素を削除する場合にも使用でき、削除の場合は、元の配列から削除した要素を格納した配列を返します。
配列から要素を削除する場合は、Array クラスにある pop()、shift()、splice() の 3 つのメソッドを使用できます。pop() メソッドでは、配列の末尾にある 1 個の要素、つまり最も大きいインデックス番号の付いた要素を削除します。shift() メソッドでは、配列の先頭にある 1 個の要素、つまりインデックス番号が 0 である要素を削除します。splice() メソッドは要素の挿入にも使用できますが、第 1 引数で指定したインデックス番号が示す位置から任意の数の要素を削除する場合にも使用できます。
これら 3 つのメソッドを使用して配列の要素を削除する例を次に示します。この例では、広い海の名前を格納するために oceans という名前の配列を作成していますが、海ではなく湖の名前がいくつか含まれているため、それらを削除します。
まず、splice() メソッドを使用して Aral および Superior の要素を削除し、Atlantic および Indian の要素を挿入します。splice() の第 1 パラメータとして渡している整数 2 は、3 番目の要素 (インデックス 2) から始まる範囲を操作対象にするという指定です。また、第 2 パラメータの整数 2 は、既存の要素を 2 つ削除するという指定です。残りのパラメータで指定している Atlantic と Indian はインデックス 2 の位置に挿入する要素のリストです。
次に、配列の末尾に位置する要素 Huron を pop() メソッドで削除します。最後に shift() メソッドで、配列の先頭に位置する要素 Victoria を削除します。
var oceans:Array = ["Victoria", "Pacific", "Aral", "Superior", "Indian", "Huron"]; oceans.splice(2, 2, "Arctic", "Atlantic"); // Aral および Superior を置換する oceans.pop(); // Huron を削除する oceans.shift(); // Victoria を削除する trace(oceans); // 出力: Pacific,Arctic,Atlantic,Indian
pop() および shift() メソッドはいずれも、削除した要素を返します。配列にはあらゆるデータ型の値を格納できるため、戻り値のデータ型は Object になっています。splice() は、削除した要素を格納した配列を返します。oceans 配列の例を次のように改変すると、splice() の呼び出しで返される戻り値を新しい配列変数に割り当てることができます。
var lakes:Array = oceans.splice(2, 2, "Arctic", "Atlantic"); trace(lakes); // 出力: Aral,Superior
配列の要素に対して delete 演算子を使用しているコードもありますが、delete 演算子はその要素の値を undefined に設定するだけであり、配列から要素を削除するわけではありません。たとえば次のコードでは、oceans 配列の 3 番目の要素に対して delete 演算子を使用していますが、配列の要素数はその後も変わらず 5 のままです。
var oceans:Array = ["Arctic", "Pacific", "Victoria", "Indian", "Atlantic"]; delete oceans[2]; trace(oceans); // 出力: Arctic,Pacific,,Indian,Atlantic trace(oceans[2]); // 出力: undefined trace(oceans.length); // 出力 : 5
配列の要素数を切り詰めるには、length プロパティを使用する方法があります。length プロパティをその配列の現状の長さより小さく設定すると配列を切り詰めることになり、変更後の length の値から 1 を引いた値よりも大きいインデックス番号を持つ要素はすべて削除されます。たとえば、oceans 配列の要素を並べ替え、残したい要素をすべて配列の先頭側に集めたとすると、次のように length プロパティを使用することで末尾側の不要な要素を削除できます。
var oceans:Array = ["Arctic", "Pacific", "Victoria", "Aral", "Superior"]; oceans.length = 2; trace(oceans); // 出力: Arctic,Pacific
配列要素の並び順を変更する場合は、ソートまたは順序の逆転を行う reverse()、sort()、sortOn() の 3 つのメソッドを使用できます。いずれのメソッドでも既存の配列が変化します。reverse() メソッドでは、配列要素の並び順を逆転します。つまり、末尾にあった要素は先頭に、末尾の直前にあった要素は 2 番目に移動します。sort() メソッドでは、さまざまな定義済みの方法で配列要素をソートできる他、独自のソートアルゴリズムを作成して使用することもできます。sortOn() メソッドでは、ソート用キーとして使用可能な複数の共通プロパティを持つオブジェクトのインデックス配列をソートできます。
reverse() メソッドは、パラメータも戻り値もありませんが、既存の配列について現在の状態と、その並び順を逆転した状態とを切り替えるのに使用できます。次の例では、oceans 配列に格納した海の名前を元とは逆の順序に並べ替えます。
var oceans:Array = ["Arctic", "Atlantic", "Indian", "Pacific"]; oceans.reverse(); trace(oceans); // 出力: Pacific,Indian,Atlantic,Arctic
sort() メソッドはデフォルトのソート順に基づいて配列要素を並べ替えます。このデフォルトのソート順には、次の特性があります。
"1" が持つ文字コードのほうがストリングの "3" が持つ文字コードよりも小さいためです。 大文字と小文字を区別しないソート、逆順のソート、またはアルファベット順でなく数値の大きさ順によるソートなどが必要な場合のために、sort() メソッドには、デフォルトのソート順に定められた各種の規則を変更する options パラメータがあります。こうしたオプションは、次に示す Array クラスの静的定数セットによって定義されます。
Array.CASEINSENSITIVE: このオプションにより、ソートで大文字と小文字が無視されます。これにより、たとえば小文字の b が大文字の D よりも先に並ぶようになります。Array.DESCENDING: デフォルトの正順ではなく逆順でソートします。たとえば、B が A よりも先に並ぶようになります。Array.UNIQUESORT: 同じ値を持つ複数の要素が見つかった場合にソートを中止するようにします。Array.NUMERIC: 数値順でソートします。たとえば、3 が 10 よりも先に並ぶようになります。これらのオプションの一部を使用した例を次に示します。poets という名前の配列を作成し、いろいろなオプションを使用してソートを実行しています。
var poets:Array = ["Blake", "cummings", "Angelou", "Dante"]; poets.sort(); // デフォルトのソート trace(poets); // 出力: Angelou,Blake,Dante,cummings poets.sort(Array.CASEINSENSITIVE); trace(poets); // 出力: Angelou,Blake,cummings,Dante poets.sort(Array.DESCENDING); trace(poets); // 出力: cummings,Dante,Blake,Angelou poets.sort(Array.DESCENDING | Array.CASEINSENSITIVE); // 2 つのオプションを併用する trace(poets); // 出力: Dante,cummings,Blake,Angelou
また、独自のソート関数を作成して sort() メソッドのパラメータに指定することもできます。たとえば、各人のフルネームを要素として格納した人名リストがあるとします。このリストを姓を基準にして並べ替える場合は、各要素を解析して姓の部分を比較するソート関数を独自に作成する必要があります。これを実現するコード例を、次に示します。この例では、カスタム関数を Array.sort() メソッドのパラメータとして使用しています。
var names:Array = new Array("John Q. Smith", "Jane Doe", "Mike Jones");
function orderLastName(a, b):int
{
var lastName:RegExp = /\b\S+$/;
var name1 = a.match(lastName);
var name2 = b.match(lastName);
if (name1 < name2)
{
return -1;
}
else if (name1 > name2)
{
return 1;
}
else
{
return 0;
}
}
trace(names); // 出力: John Q. Smith,Jane Doe,Mike Jones
names.sort(orderLastName);
trace(names); // 出力: Jane Doe,Mike Jones,John Q. Smith
独自のソート関数 orderLastName() では、正規表現を使用して各要素から姓の部分を抽出し、それを比較演算に使用します。names 配列に対する sort() メソッド呼び出しのパラメータとして、この関数の識別子である orderLastName だけを指定しています。ソート関数に a および b の 2 つのパラメータが渡されるのは、一度に 2 つの配列要素が処理の対象となるからです。ソート関数の戻り値は 2 つの要素の並び順を示すものであり、次の意味があります。
a を第 2 パラメータの b よりも先に並べることを示します。 b を第 1 パラメータの a よりも先に並べることを示します。 sortOn() メソッドは、要素がオブジェクトであるインデックス配列のためにあります。すべての要素のオブジェクトには、ソート用キーとなる共通のプロパティが少なくとも 1 つ含まれている必要があります。これらの条件に合わない配列に対して sortOn() メソッドを使用した場合の結果は予測不能です。
次の例は、poets 配列をストリング要素ではなくオブジェクト要素の配列に改変したものです。各オブジェクトには、詩人の姓と生誕年が格納されています。
var poets:Array = new Array();
poets.push({name:"Angelou", born:"1928"});
poets.push({name:"Blake", born:"1757"});
poets.push({name:"cummings", born:"1894"});
poets.push({name:"Dante", born:"1265"});
poets.push({name:"Wang", born:"701"});
この配列では、born プロパティを基準として sortOn() メソッドによるソートを実行できます。sortOn() メソッドには、fieldName および options の 2 つのパラメータがあります。fieldName にはストリングを指定する必要があります。次の例では、sortOn() にパラメータとして "born" および Array.NUMERIC の 2 つを渡しています。Array.NUMERIC オプションを指定しているのは、アルファベット順ではなく数値順で確実にソートを実行するためです。たとえ各要素に格納されている数値の桁数がすべて同じであっても、必ずこのオプションを指定するようにしておけば、後で桁数の異なる要素が追加されたとしても正常に動作します。
poets.sortOn("born", Array.NUMERIC);
for (var i:int = 0; i < poets.length; ++i)
{
trace(poets[i].name, poets[i].born);
}
/* 出力 :
Wang 701
Dante 1265
Blake 1757
cummings 1894
Angelou 1928
*/
一般に、sort() および sortOn() メソッドを使用すると元の配列が変化します。既存の配列を変更せずにソートを実行する場合は、options パラメータに Array.RETURNINDEXEDARRAY 定数を含めます。このオプションを指定した場合、メソッドの戻り値はソート結果を示す新しい配列となり、元の配列の内容はそのまま維持されます。返される配列はソート後の並び順を示すインデックス番号だけを格納した単純なものであり、元の配列内の要素を格納した配列ではありません。たとえば、poets 配列について元の状態を維持したまま生誕年でのソートを実行するには、options パラメータに Array.RETURNINDEXEDARRAY 定数を含めます。
次の例では、戻り値のインデックス情報を indices という配列に格納し、この indices と元のままの poets を使用して詩人のリストを生誕年順に表示しています。
var indices:Array;
indices = poets.sortOn("born", Array.NUMERIC | Array.RETURNINDEXEDARRAY);
for (var i:int = 0; i < indices.length; ++i)
{
var index:int = indices[i];
trace(poets[index].name, poets[index].born);
}
/* 出力 :
Wang 701
Dante 1265
Blake 1757
cummings 1894
Angelou 1928
*/
以上で説明した他に、Array クラスには concat()、join()、slice()、toString() の 4 つのメソッドがあります。これらはいずれもクエリによって配列から情報を取得するものであり、配列に変更を加えることはありません。concat() および slice() メソッドは新しい配列を返し、join() および toString() メソッドはストリングを返します。concat() メソッドのパラメータには配列または要素リストを指定します。既存の配列と、パラメータで指定した別の配列または要素とを連結し、新しい配列を作成して返します。slice() メソッドには、startIndex および endIndex という 2 つのパラメータがあります。元の配列から、これらのパラメータで指定したインデックスの範囲を切り出し、その部分のコピーを格納した新しい配列を返します。ただし、返される範囲は startIndex が指す要素から、endIndex が指す要素の直前までであり、endIndex の位置にある要素は含まれません。
次の例では、既存の配列から concat() および slice() を使用して新しい配列を作成します。
var array1:Array = ["alpha", "beta"];
var array2:Array = array1.concat("gamma", "delta");
trace(array2); // 出力: alpha,beta,gamma,delta
var array3:Array = array1.concat(array2);
trace(array3); // 出力: alpha,beta,alpha,beta,gamma,delta
var array4:Array = array3.slice(2,5);
trace(array4); // 出力: alpha,beta,gamma
join() および toString() メソッドでは、配列の内容をストリングとして取得できます。join() メソッドのパラメータを指定しない場合、これら 2 つのメソッドはいずれも、すべての配列要素をカンマで区切った内容のストリングを返します。join() メソッドには、toString() メソッドにない delimiter というパラメータがあり、戻り値のストリングで要素間に使用する区切り文字を指定できます。
次の例では rivers という配列を作成し、join() および toString() を呼び出すことで、配列の内容をストリングとして取得します。toString() メソッドはカンマ区切りの値 (riverCSV) を得るため、また、join() メソッドは + で区切った値を得るために使用しています。
var rivers:Array = ["Nile", "Amazon", "Yangtze", "Mississippi"];
var riverCSV:String = rivers.toString();
trace(riverCSV); // 出力: Nile,Amazon,Yangtze,Mississippi
var riverPSV:String = rivers.join("+");
trace(riverPSV); // 出力: Nile+Amazon+Yangtze+Mississippi
join() メソッドを使用する場合には、メインの配列要素に対して指定する区切り文字に関係なく、次に示す例のように、ネストされた配列には常にカンマ区切りの値が返されることに注意する必要があります。
var nested:Array = ["b","c","d"];
var letters:Array = ["a",nested,"e"];
var joined:String = letters.join("+");
trace(joined); // 出力: a+b,c,d+e
このページに新しいコメントが追加された場合に、電子メールでの通知を希望する。 | コメントレポート
現在のページ: http://livedocs.adobe.com/flash/9.0_jp/main/00000089.html