配列

■ 配列に値を設定する

◆ 配列とは

配列は、@配列名 で表します。各要素は $配列名[添字] で表します。配列の場合、添字には 0 から始まる(※)整数値を用います。

◆ 配列に値を設定する方法

配列に値を代入するには、各要素にひとつづつ代入するか、(..., ...) や qw(...) を用いて一度に代入します。qw(...) の場合、文字列はクォートで囲まず、カンマ(,)も記述しないことに注意してください。

array1.pl
# (1) ひとつひとつ代入する方法
$aaa[0] = "Tanaka";
$aaa[1] = "Suzuki";
$aaa[2] = "Yamada";
print "aaa = @aaa\n";

# (2) (..., ...) を用いる方法
@bbb = ( "Tanaka", "Suzuki", "Yamada" );
print "bbb = @bbb\n";

# (3) qw(...) を用いる方法
@ccc = qw( Tanaka Suzuki Yamada );
print "ccc = @ccc\n";

実行結果は次のようになります。

aaa = Tanaka Suzuki Yamada
bbb = Tanaka Suzuki Yamada
ccc = Tanaka Suzuki Yamada
◆ 配列の添え時に関する補足

※ 正確には、配列の添字は特殊変数 $[ の値から始まります。例えば、$[ に 1 を代入しておくと、配列の添字は 0, 1, 2, ... ではなく、1, 2, 3, ... となります。

$[ = 1;
@xxx = ( "AAA", "BBB", "CCC" );
print "$xxx[1]\n";
print "$xxx[2]\n";
print "$xxx[3]\n";

■ 配列を参照する

◆ forで参照する

for 文で配列を参照します。$#配列名 は配列の添字の最大値を示します。

array2.pl(1)
@aaa = ( "Tanaka", "Suzuki", "Yamada" );
for ($i = 0; $i <= $#aaa; $i++) {
    print "$aaa[$i] ";
}
print "\n";
◆ foreachで参照する

foreach 文では、配列の各要素が順順に $name に代入されながら、処理が実行されます。

array2.pl(2)
@aaa = ( "Tanaka", "Suzuki", "Yamada" );
foreach $name (@aaa) {
    print "$name ";
}
print "\n";
◆ foreachのループ変数を省略する

foreach では $name を省略することができます。この場合、省略時変数 $_ に値が代入されます。

array2.pl(3)
@aaa = ( "Tanaka", "Suzuki", "Yamada" );
foreach (@aaa) {
    print "$_ ";
}
print "\n";

■ 配列を表示する

◆ 配列変数をそのまま表示する

配列の変数を print 文で直接書き出すと、各要素が連結されて(正確には特殊変数 $, の値で区切られて)表示されます。

array3.pl(1)
@aaa = ( "Tanaka", "Suzuki", "Yamada" );

# (1) $,(通常は空文字)の値で区切られて表示される
print @aaa;
print "\n";

実行結果は次のようになります。

TanakaSuzukiYamada
◆ "..." の中で参照する

"..." で囲んで書き出すと、各要素がスペース(正確には特殊変数 $" の値で区切られて)表示されます。

array3.pl(2)
# (2) $"(通常は空白文字)の値で区切られて表示される
print "@aaa";
print "\n";

実行結果は次のようになります。

Tanaka Suzuki Yamada
◆ スカラー変数に代入する

配列変数をスカラー変数に代入してしまうと、配列はその個数を返します。

array3.pl(3)
# (3) スカラー変数に代入すると個数を返す
$str = @aaa;
print "$str\n";

実行結果は次のようになります。

3

■ 配列に追加・削除する(pop, push, shift, unshift)

◆ 配列の末尾に追加(push)

push(array, elem) は、配列 array の末尾に要素 elem を追加し、追加後の要素の個数を返します。

array4.pl(1)
@abc = ( "AAA", "BBB", "CCC" );
$num = push(@abc, "DDD");
print "push:    num=$num, abc=[@abc]\n";
◆ 配列の末尾を取り出す(pop)

pop(array) は、配列 array から末尾の要素を削除し、削除した要素を返します。

array4.pl(2)
@abc = ( "AAA", "BBB", "CCC" );
$elm = pop(@abc);
print "pop:     elm=$elm, abc=[@abc]\n";
◆ 配列の先頭に追加(push)

unshift(array, elem) は、配列 array の先頭に要素 elem を追加し、追加後の要素の個数を返します。

array4.pl(3)
@abc = ( "AAA", "BBB", "CCC" );
$num = unshift(@abc, "DDD");
print "unshift: num=$num, abc=[@abc]\n";
◆ 配列の先頭を取り出す(shift)

shift(array) は、配列 array から先頭の要素を削除し、削除した要素を返します。

array4.pl(4)
@abc = ( "AAA", "BBB", "CCC" );
$elm = shift(@abc);
print "shift:   elm=$elm, abc=[@abc]\n";
◆ 実行結果

それぞれの実行結果は次のようになります。

push:    num=4, abc=[AAA BBB CCC DDD]
pop:     elm=CCC, abc=[AAA BBB]
unshift: num=4, abc=[DDD AAA BBB CCC]
shift:   elm=AAA, abc=[BBB CCC]

■ 配列の途中の要素を追加・削除・置換する(splice)

◆ 配列の途中の要素を置換する

splice() は splice(配列1, from, n, 配列2) のように使用し、配列1 の(0から数えて)from 番目から n 個分の要素を、配列2 で置き換えます。

splice.pl(1)
@abc = ( "AAA", "BBB", "CCC", "DDD", "EEE" );
splice(@abc, 2, 2, "ccc", "ddd");   # "CCC", "ddd" を小文字に置換する
print "@abc\n";

実行結果は次のようになります。

AAA BBB ccc ddd EEE
◆ 配列の途中の要素を削除する

引数の 配列2 を省略すると、from 番目から n 個の要素の削除になります。

splice.pl(2)
@abc = ( "AAA", "BBB", "CCC", "DDD", "EEE" );
splice(@abc, 2, 2);                 # "CCC", "DDD" を削除する
print "@abc\n";

実行結果は次のようになります。

AAA BBB EEE
◆ 配列の途中に要素を追加する

n 個の部分に 0 を指定すると、0 個分の要素を 配列2 で置換、つまり、追加になります。

splice.pl(3)
@abc = ( "AAA", "BBB", "EEE" );
splice(@abc, 2, 0, "CCC", "DDD");   # "CCC", "DDD" を追加する
print "@abc\n";

実行結果は次のようになります。

AAA BBB CCC DDD EEE

■ 配列を連結する(join)

◆ 配列の連結(join)

join(sep, array) は、sep を区切り文字として配列 array を連結し、その結果を返します。下記の例では、"23", "59", "59" の文字列からなる配列をコロン(:)で連結します。

join.pl
@time = ( "23", "59", "59" );
$time = join(":", @time);
print "time = $time\n";

$date = join("/", "1999", "12", "31");
print "date = $date\n";

結果は次のようになります。

time = 23:59:59
date = 1999/12/31

■ 配列を辞書順にソートする(sort)

◆ 文字列のソート

sort() は、配列の各要素を辞書順にソートし、その結果の配列を返します。

sort1.pl
@abc = ( "BBB", "CCC", "AAA" );
@abc = sort(@abc);
print "@abc\n";

結果は次のようになります。

AAA BBB CCC

数値をソートすると 1, 10, 2, ... の順になってしまいます。数値の場合は次項を参照してください。

■ 配列を数値順にソートする(sort)

◆ 数値のソート

「sort { 比較条件 } 配列」の形式を用いることにより、辞書順以外のソートが可能になります。比較条件では $a と $b を比較し、$a が小さければ負の値、等しければ 0、大きければ正の値を返すようにします。これにより、配列を数値順にソートし、その結果を返すことができます。

sort2.pl
@aaa = ( 1, 10, 5 );
@aaa = sort { $a <=> $b } @aaa;
print "@aaa\n";

結果は次のようになります。

1 5 10

逆順にソートする場合は $a と $b を入れ替えてください。

@aaa = sort { $b <=> $a } @aaa;

■ 高度な比較で配列をソートする(sort)

◆ 複雑な条件によるソート

比較条件をサブルーチンとして定義することにより、さらに複雑な条件によるソートが可能になります。サブルーチン(ソート関数)では、2 つの要素を $a と $b で受け取り、等しい時は 0、$a が大きいときは正の値、$a が小さいときは負の値を返すようにしてください。例では、文字数によるソートを行っています。(これはまだ単純なので、sort { length($a) <=> length($b) } @aaa; でも実現できます。)

sort3.pl
@aaa = ( "AA", "AAA", "A" );
@aaa = sort hikaku @aaa;
print "@aaa\n";

sub hikaku {
    my($alen) = length($a);
    my($blen) = length($b);

    if ($alen == $blen) {
        return 0;
    } elsif ($alen > $blen) {
        return 1;
    } elsif ($alen < $blen) {
        return -1;
    }
}

結果は次のようになります。

A AA AAA

■ 配列を逆順に並び替える(reverse)

◆ 逆順の並び替え

reverse() は配列を逆順に並び替えたものを返します。逆順ソートという訳ではないので注意してください。

reverse.pl
@xx = ( "J", "a", "p", "a", "n" );
@xx = reverse(@xx);
print "@xx\n";

結果は次のようになります。

n a p a J

■ 条件にあうものだけを抜き出す(grep)

◆ 条件にマッチするものの抜き出し

grep() は、配列の中から 正規表現 で指定した条件にあうものだけを抜き出します。例では Sun, Mon, ... の中から先頭が S で始まるものだけを抜き出します。

grep.pl
@xx = ( "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" );
@xx = grep(/^S/, @xx);
print "@xx\n";

結果は次のようになります。

Sun Sat

■ 各要素に対して処理を行う(map)

◆ 説明

map() は、配列の各要素に対して簡単な処理を行います。例では、数値 1, 2, 3 それぞれに対して平方根(sqrt)を求め、その結果を @roots に代入しています。

map.pl
@nums = ( 1, 2, 3 );
@roots = map(sqrt, @nums);
print "@roots\n";

結果は次のようになります。

1 1.4142135623731 1.73205080756888

処理の部分は、次のように指定することも可能です。

@nums = ( 1, 2, 3 );
@roots = map { sqrt($_); } @nums;
print "@roots\n";

■ 多次元配列を使用する

◆ 多次元配列

$配列名[添字][添字] とすることにより、多次元の配列を用いることが可能です。下記の例では、$xx[0][0] に 0、$xx[0][1] に 1、$xx[0][2] に 2 ... が代入されていきます。

marray.pl
for ($i = 0; $i < 10; $i++) {
    for ($j = 0; $j < 10; $j++) {
        $xx[$i][$j] = $i * 100 + $j;
    }
}
print "$xx[4][5]\n";

結果は次のようになります。

405

Copyright (C) 2002 杜甫々