[PR]今日のニュースは
「Infoseek モバイル」




配列を使用したい






■配列を作成する


配列型の変数を作成するには Array クラスを使用します。


配列型の変数を作成する

var ary = new Array();


データを代入するときは、[ ] を付けて、好きな番地を指定します。マイナスの値を指定する事もできますが、通常は 0 から順番に使用します。


配列にデータを格納する

var ary = new Array();

ary[0] = 0;
ary[1] = 123;
ary[2] = "テスト";


データを取り出すときも、[ ] を付けて、好きな番地を指定します。


配列からデータを取り出す

var ary = new Array();

ary[0] = 0;
ary[1] = 123;
ary[2] = "テスト";

trace( ary[0] );
trace( ary[1] );
trace( ary[2] );





■配列の特殊な初期化方法


Array クラスを使わずに、データを格納しつつ配列を作成する方法があります。
[ ] の中に , で区切りながらデータを記述して変数に渡します。

Array クラスを使わず、各番地を初期化でき、かつ高速に動作するのでとても便利です。


配列用の初期化を利用して配列型の変数を作成する

var ary = [ 0, 123, "テスト" ];







2次元配列を使用したい






■2次元配列を作成する


2次元配列を作成するには Array クラスを使って配列を作った後、各番地にさらに配列型の変数を格納していきます。


[4][*]の2次元配列を作成する

var ary = new Array();
ary[0] = new Array();
ary[1] = new Array();
ary[2] = new Array();
ary[3] = new Array();


for文を使って記述すると下のようになります。


[4][6]の2次元配列を作成して各番地を 0 で初期化する

var ary = new Array();

var i,j;
for(i=0;i < 4;i++){
	ary[i] = new Array();
	for(j=0;j < 6;j++){
		ary[i][j] = 0;
	}
}


データを代入するときは、[ ] を2つ付けて、好きな番地を指定します。


配列にデータを格納する

var ary = new Array();
ary[0] = new Array();
ary[1] = new Array();

ary[0][0] = 0;
ary[1][1] = 123;
ary[1][2] = "テスト";


データを取り出すときも、[ ] を2つ付けて、好きな番地を指定します。


配列からデータを取り出す

var ary = new Array();
ary[0] = new Array();
ary[1] = new Array();

ary[0][0] = 0;
ary[1][1] = 123;
ary[1][2] = "テスト";

trace( ary[0][0] );
trace( ary[1][1] );
trace( ary[1][2] );







■配列の特殊な初期化方法


Array クラスを使わずに、データを格納しつつ配列を作成する方法があります。[ ] の中に , で区切りながらデータを記述して変数に渡します。

2次元配列の場合、配列の各番地にさらに配列を作ればいいので [ ] のなかでさらに [ ] を作り配列を作成します。


配列用の初期化を利用して2次元配列を作成する

var ary = [
	[ 1, 2, 3 ],
	[ "a", "b", "c" ],
	[ "abc", "テスト" ]
];







配列のメソッドを使用したい






■Array クラスのメソッド一覧


Array クラスには、以下のメソッドが存在します。


メソッド 説明
concat() 配列同士をつなげる。
shift() 配列の先頭のデータを削除して結果を返す。
unshift() 配列の先頭にデータを追加して長さを返す。
pop() 配列の最後のデータを削除して返す。
push() 配列の最後にデータを追加して長さを返す。
slice() 配列の?番目から?番目を配列として返す。
splice() 配列の?番目から?個を削除して1つの値を追加する。
sort() 配列をソートする。
sortOn() (Flash 6 以降)共通するプロパティを持つオブジェクトが格納された配列をソートする。
reverse() 配列の順番を逆にする。
join() 配列データの間に文字を挟みすべて繋げてストリングにして返す。
toString() 配列データをすべて繋げてストリングにして返す。





例) 配列をつなげて新しい配列を作成する。

var a = [1 ,2 ,3];
var b = ["A" ,"B" ,"C"];
var c = [4 ,5 ,6];
var d = ["D" ,"E" ,"F"];

var z = a.concat(b,c,d);







例) 配列の先頭のデータを削除して削除したデータを返す

var a = ["A" ,"B" ,"C" ,"D" ,"E"];
var z = a.shift();







例) 配列の先頭に"D","E","F"を追加して長さを返す

var a = ["A" ,"B" ,"C"];
var z = a.unshift("D" ,"E" ,"F");







例) 配列の最後を削除して削除したデータを返す。

var a = ["A" ,"B" ,"C" ,"D"];
var z = a.pop();







例) 配列の最後に"D","E","F"を追加して長さを返す

var a = ["A" ,"B" ,"C"];
var z = a.push("D" ,"E" ,"F");







例) 配列の1番目から3番目を新しい配列として返す

var a = ["A" ,"B" ,"C" ,"D" ,"E" ,"F"];
var z = a.slice(1, 4);







例) 配列の1番目から3個分削除してその間に"G","H","I"を追加する

var a = ["A" ,"B" ,"C" ,"D" ,"E" ,"F"];
var z = a.splice(1, 3 ,"G","H","I");







例) 配列をソートする。

var a = [2, 4, 1, "B", "C", 3, 0, "A"];
a.sort();







例) プロパティ id を元に配列を文字ソートする。(Flash 6 以降)

var a = [
	{ id : 14, data0 : "データ1", data1 : "データA" },
	{ id :  1, data0 : "データ2", data1 : "データB" },
	{ id :  2, data0 : "データ3", data1 : "データC" },
	{ id :  5, data0 : "データ4", data1 : "データD" },
	{ id : 10, data0 : "データ5", data1 : "データE" },
	{ id :  3, data0 : "データ6", data1 : "データF" }
];
a.sortOn("id");






例) プロパティ id を元に配列を数値ソートする。(Flash 7 以降)

var a = [
	{ id : 14, data0 : "データ1", data1 : "データA" },
	{ id :  1, data0 : "データ2", data1 : "データB" },
	{ id :  2, data0 : "データ3", data1 : "データC" },
	{ id :  5, data0 : "データ4", data1 : "データD" },
	{ id : 10, data0 : "データ5", data1 : "データE" },
	{ id :  3, data0 : "データ6", data1 : "データF" }
];
a.sortOn("id",Array.NUMERIC);







例) 配列の順番を逆にする。

var a = [0, 1, 2, 3, 4];
a.reverse();







例) 配列の各番地のデータに文字を挟んで繋げて1つの文字列として返す。

var a = [0, 1, 2, 3, 4 ,"a" ,"b" ,"c"];
var z = a.join("-");







例) 配列の各番地のデータに","を挟んで繋げて1つの文字列として返す。

var a = [0, 1, 2, 3, 4 ,"a" ,"b" ,"c"];
var z = a.toString();







■Array クラスのプロパティ


Array クラスには、以下のメソッドが存在します。


プロパティ 説明
length 配列が使用している番地の数。





例) 配列の数を調べる

var a = [0, 1, 2, 3, 4 ,"a" ,"b" ,"c"];
var num = a.length;






オブジェクトを使用したい






■オブジェクトを使用する


オブジェクト型の変数を作成するには Object クラスを使用します。


Object型の変数を作成する

var obj = new Object();


データを代入するときは、. を付けて、好きなプロパティ名を指定します。


オブジェクトにデータを格納する

var obj = new Object();

obj.num = 0;
obj.dat = 123;
obj.str = "テスト";


データを取り出すときも、. を付けて、好きなプロパティ名を指定します。


オブジェクトからデータを取り出す

var obj = new Object();

obj.num = 0;
obj.dat = 123;
obj.str = "テスト";

trace( obj.num );
trace( obj.dat );
trace( obj.str );


配列は数値を使って管理しますが、オブジェクトは文字名を使って管理するのが特徴です。





■オブジェクトの特殊な初期化方法


Object クラスを使わずに、データを格納しつつオブジェクトを作成する方法があります。
{ } の中に , で区切りながら『インスタンス名 : データ』という書式で記述したものを、変数に渡します。

Object クラスを使わず、各プロパティを初期化でき、かつ高速に動作するのでとても便利です。


オブジェクト用の初期化を利用してオブジェクト型の変数を作成する

var obj = {
	num : 0,
	dat : 123,
	str :  "テスト"
};







木構造のオブジェクトを使用したい






■オブジェクトで木構造のデータを作る


木構造を持つオブジェクトを作成するには Object クラスを使って配列を作った後、各プロパティにさらにオブジェクト型の変数を格納していきます。


木構造を持つオブジェクトを作成する

var obj = new Object();
obj.data0 = new Object();
obj.data1 = new Object();
obj.data2 = new Object();
obj.data2.data = new Object();


データを代入するときは、. を付けてプロパティ名を指定していきます。


配列にデータを格納する

var obj = new Object();
obj.data0 = new Object();
obj.data1 = new Object();
obj.data2 = new Object();
obj.data2.dat = new Object();

obj.data0.num = 0;
obj.data0.dat = 123;
obj.data0.str = "テスト1";
obj.data1.num = 1;
obj.data1.dat = 456;
obj.data1.str = "テスト2";
obj.data2.num = 2;
obj.data2.str = "テスト3";
obj.data2.dat.num = 3;
obj.data2.dat.str = "テスト4";


データを取り出すときも、. を付けてプロパティ名を指定していきます。


配列からデータを取り出す

var obj = new Object();
obj.data0 = new Object();
obj.data1 = new Object();
obj.data2 = new Object();
obj.data2.dat = new Object();

obj.data0.num = 0;
obj.data0.dat = 123;
obj.data0.str = "テスト1";
obj.data1.num = 1;
obj.data1.dat = 456;
obj.data1.str = "テスト2";
obj.data2.num = 2;
obj.data2.str = "テスト3";
obj.data2.dat.num = 3;
obj.data2.dat.str = "テスト4";

trace( obj.data0.num );
trace( obj.data0.dat );
trace( obj.data0.str );
trace( obj.data1.num );
trace( obj.data1.dat );
trace( obj.data1.str );
trace( obj.data2.num );
trace( obj.data2.str );
trace( obj.data2.dat.num );
trace( obj.data2.dat.str );









■オブジェクトの特殊な初期化方法


Object クラスを使わずに、データを格納しつつオブジェクトを作成する方法があります。
{ } の中に , で区切りながら『インスタンス名 : データ』という書式で記述したものを、変数に渡します。

木構造の場合、オブジェクトの各プロパティにさらにオブジェクトを作ればいいので { } のなかでさらに { } を作りオブジェクトを作成します。


オブジェクト用の初期化を利用して木構造を持つオブジェクトを作成する

var obj = {
	data0 : {
		num : 0,
		dat : 123,
		str : "テスト1"
	},
	data1 : {
		num : 1,
		dat : 456,
		str : "テスト2"
	},
	
	data2 : {
		num : 2,
		dat : { num : 3, str : "テスト4" },
		str : "テスト3"
	}
};







参照(リファレンスデータ)について






■参照渡し


下のように配列 a を作ってみました。


配列 a を作成する

var a = [0,1,2,3,4,5];


この変数 a は[ 0,1,2,3,4,5 ]という5つのデータを持っています。


ここで、変数 a を変数 b に渡すとどうなるのでしょうか?
中身がすべて変数 b にコピーされるような気がします。


配列 a を そのまま変数 b に渡す

var a = [0,1,2,3,4,5];
var b = a;


デバッガ機能を使って変数を確認してみましょう。




変数 a と 変数 b は同じ値を持っています。 ということはやはり中身がコピーされたのでしょうか?確認するためにもうひとつ別のテストをしてみましょう。

変数 b の2番目のインデックスに別の値を代入してみましょう。


配列 a を そのまま変数 b に渡した後 b[2] を変更する

var a = [0,1,2,3,4,5];
var b = a;
b[2] = 6;


この状態でデバッガで確認してみましょう。




変数 b の2番目のインデックスが 6 に変わりました。しかし同時に、
変数 a の 2 番目のインデックスも 6 に変わってしまいました。

これは何が起こっているのでしょうか?





■配列の作られ方


配列を作ったときにその変数自身にデータが格納されるように見えますが、実際のデータはメモリ上の不特定の位置に確保されています。

例えば、下のように配列を作ったとします。


配列 a を作成

var a = [0,1,2,3,4,5];


メモリ上のどこかにデータ [0,1,2,3,4,5] を格納するための場所が確保され、その場所にアクセスするための参照データが変数 a に代入されます。

デバッガの画面で表すと下のようなイメージになります。




ということは、変数 a から変数 b に代入すると下のようなイメージになります。


配列 a を そのまま変数 b に渡す

var a = [0,1,2,3,4,5];
var b = a;





変数 a に入っているのは、メモリ上の『配列のデータを確保している場所』までの参照です。この参照を変数 b にコピーして渡しました。
つまり、変数 a からも 変数 b からも同じ、メモリ上に確保された配列のデータにアクセスできるようになります。



この参照データを他の変数に渡す行為を参照渡しといいます。





■メモリーリーク


作られた配列を消すにはどうすれば良いのでしょうか?
例えば下のソースを見てみましょう。


配列 a を作成

var a = [0,1,2,3,4,5];


この変数 a になにか適当な値を代入してやれば配列データが消えるような気がします。


変数 a に配列を作成してから適当な値で上書きする

var a = [0,1,2,3,4,5];
a = 6;


デバッガでも確認してみましょう。




配列データがありませんね。ということは、消えてしまったのでしょうか?

答えを言うと、実際は消えていません。実際のメモリの中身は下の図のようなイメージになります。まず、配列 a を作った状態です。




ここで変数 a に適当な値を入れると下の図のようになります。




ここでのポイントは、配列データはメモリ上に残っているのに、そこにアクセスするための『参照データ』を消してしまったため配列データにアクセスする手段が無くなった事です。

アクセスできなくなったという事は、削除する事もできないので永遠にメモリ上に残る事になりそうです。この参照する事ができなくなり、メモリ上に永遠に残ってしまう状態を、メモリリークといいます。





■ガベージコレクション


どこからも参照されなくなった配列データは、メモリ上に永遠に残ってしまうのでしょうか?

いいえ、FlashPlayer にはこのメモリリークしたゴミを自動的に解放してくれる機能があります。これをガベージコレクションと言います。

という事で、プログラマはメモリリークを起こしているかといった事を気にせずアクションスクリプトを組んでいく事ができます。





■ガベージコレクションの注意点


ガベージコレクションが回収するのは、誰からも参照されなくなったメモリ部分だけです。プログラムから1箇所でもアクセスできる状態であれば解放される事はありません。

ということは、ガベージコレクションで解放されているなと予想してても、どこかのグローバル変数に参照を渡してしまっていたために解放されずに、メモリを食いつぶしていくという事が起こりうるので気をつけないといけません。 タスクマネージャを起動してメモリが増えていないか確認するといいでしょう。


また、ガベージコレクションは自動的に不定期に動作します。処理自体はとても重く、FlashPlayerがたまにガクッと画面が止まってしまうのはこれが原因のひとつと考えられます。





■手動で消す場合


delete 命令文を使うと、手動ですぐに破棄することが出来ます。


配列 a を破棄する

var a = [0,1,2,3,4,5];
delete a;





■その他の参照データ


配列以外にも参照データになっているものがあります。

『Object』や『function』や『クラス』は参照(リファレンス)データという扱いになります。 他の変数に代入すると、参照渡しとなりその変数からでもアクセス可能になります。

通常の変数である、『Number』 や 『String』は、プリミティブデータという扱いになります。他の変数に代入すれば、データを丸ごとコピーします。