MTでPerlを学ぶ(その16・配列(2))

前回から2か月以上あいてしまいましたが、「MTでPerlを学ぶ」の第16回です。
今回は、前回に続いて配列の話です。

1.インデックスを変数で指定する

配列のインデックスは、定数だけでなく、変数で指定することもできます。
たとえば、変数$iの値が3になっているとすると、「$points[$i]」は、配列@pointsの3番目の要素を表すことになります。

インデックスを変数で指定できることで、大量のデータを効率良く扱いやすくなります。
for文やwhile文等の繰り返しと組み合わせて、配列内のすべての要素を順に処理することがよくあります。

たとえば、配列変数@pointsがあって、要素が10個(インデックスが0~9)あるとします。
ここで、この配列の各要素の平均を求めたいとしましょう。

平均は、全部のデータを合計して、データの個数で割った値です。
そこで、for文を使って繰り返しを行い、配列の全要素の合計を求めます。

実際に、平均を求める処理を作ると、以下のようになります。

my $sum = 0;
for (my $i = 0; $i < 10; $i++) {
    $sum += $points[$i];
}
my $avg = $sum / 10;
print "平均は $avg です。";

上記を含むインデックステンプレートのサンプルをダウンロード

各行の内容は以下の通りです。

1行目:my $sum = 0;

まず、配列の全要素の合計を求めます。
合計は変数$sumに代入することにします。そこで、変数$sumを宣言して、値を0に初期化しておきます。

2行目:for (my $i = 0; $i < 10; $i++) {

配列@pointsには10個の要素がありますので、10回の繰り返しを行います。
繰り返しの中で、変数$iは0、1、・・・、9と順に変化します。

3行目:$sum += $points[$i];

変数$sumに、配列@pointsの$i番目の要素の値を足し算します。

for文の繰り返しによって、$iは0、1、・・・、9と順に変化します。
したがって、$sumには$points[0]、$points[1]、・・・、$points[9]と順に足し算することになり、$sumに配列@pointsの全要素の合計を求めることができます。

5行目:my $avg = $sum / 10;

変数$sumの値をデータ数の10で割って平均を求め、変数$avgに代入します。

6行目:print "平均は $avg です。";

結果を出力します。

2.配列の要素数を得る

ここまでで取り上げた例では、配列の要素は10個であると決め打ちにしていました。
しかし、実際のプログラムの中では、配列の要素の数が状況によって変わることもあります。
そのような場合、配列の要素の数を調べて、その数に応じた処理をする必要が出ます。

配列の要素の数は、「scalar(@配列変数名)」で得ることができます。
たとえば、配列変数@pointsの要素数は、「scalar(@points)」で得ることができます。

この書き方を使って、先ほどの平均を求める例を、配列の要素数に応じた動作になるように変えてみます。
ハイライトの行が、追加または変更した行です。

my $sum = 0;
my $count = scalar(@points);
for (my $i = 0; $i &lt; $count; $i++) {
    $sum += $points[$i];
}
my $avg = $sum / $count;
print "平均は $avg です。";

上記を含むインデックステンプレートのサンプルをダウンロード

元のリストでは、for文の「$i < 10;」のところと、平均を求める「my $avg = $sum / 10;」のところで、要素数の「10」を直接に書いていました。
これらの箇所を変えます。

まず、2行目の「my $count = scalar(@points);」の文で、配列@pointsの要素数を求めて、変数$countに代入します。
そして、for文(3行目)と平均を求める行(6行目)の「10」を、変数$countに置き換えます。