<データ構造の入れ子>
>>素直に多次元配列と呼ばないわけ
Perlでは(ちなみにCでも)多次元配列は1次元配列の入れ子、すなわち「配列の配列」の形で実現されているから。
ついでにもう1つ、ハッシュの配列、配列のハッシュ、ハッシュのハッシュなんかも扱うから。
リファレンス
基本的に、入れ子構造を作るにはリファレンスを使う。
たとえば、2次元配列@array[N][M]を作りたい場合は、1次元配列@subarray[M]をN個用意し、
それぞれへのリファレンスを1次元配列@array[N]に順次格納していく。
>>静的配列・ハッシュ
静的なデータ、つまりスクリプト内に直接書いてしまえるような値が決まりきっている配列やハッシュの場合は少し横着が利く。
[]や
{}で囲まれたデータは、
それぞれ
無名の配列、
無名のハッシュへのリファレンスと見なされる(?:あやしい)。
「無名」というのは、メモリ上のあるアドレスにデータは存在するが、そのアドレスに対応する名前がない、と言う意味である。
よってリファレンスとして使う分にはまったく問題ない。
そこで、
@array = (
[1,0,0],
[0,1,0],
[0,0,1],
);
とすれば、これだけで2次元配列ができる。
利用するときは、$array[i][j]とすればよい。ただし、この記法は省略記法であることに注意。
>>動的配列・ハッシュ
少し面倒だが、データ構造を作る時はそんなに難しくない。
利用するときも、書き方がややこしいだけで難しくはない。
同じように配列、ハッシュへのリファレンスを順次格納していくだけ。
この「順次格納」という作業は大抵ループを使ってやることになるだろうが、
格納するデータをしまっておく変数はループ外で定義してはいけない。
なぜなら、格納するのはリファレンスなので、ループ外で定義された変数の場合、
ループ内でいくら値を変えてもアドレスは変わらないからである。
従ってループ内で定義する必要があるが、今度はループが回るたびに
格納したリファレンスの実体が消滅してしまうのではないか、という事が心配になる。
その辺perlはよくできていて、実体(つまりあるアドレスにあるデータ)は、
そこへのリファレンスが存在している限り破棄されない。だから、心配しないでどんどんループを回して良い。
ハッシュのハッシュ:
my %hash; #親ハッシュの定義
foreach my $datatemp (@data){
my %subhash; #格納用ハッシュの定義
my $subkey; #格納用ハッシュのキー
# $datatempからデータを切り出す処理
# 切り出したデータを%subhashに格納する処理
# たとえば、$subhash{'english'}='cat';
$hash{$subkey} = \%subhash; # 親ハッシュに子ハッシュのリファレンスを代入
}
#利用
print ${$hash{'neko'}}{'english'}; # cat
accend->Perl->labnote->index page