[Perlトップページ]

配列とリスト

リストと配列

リストとは、コンマで区切ってカッコでくくったもの のことです。たとえば、下記の例1、2はそれぞれリストです。

例1: ('飯沼', '岩橋', '菊池', '吉田')
例2: (201, 32, 29)

このリストを配列と呼ばれる変数に入れると、 その後の処理が楽になります。その処理の過程は後程説明するとして、 上記のリストを配列変数に入れるとすると、

例1: @name = ('飯沼', '岩橋', '菊池', '吉田');
例2: @score = (201, 32, 29);

とすることで、配列変数@name, @scoreにリストが入ることになります。

このリストを生成するときですが、1ずつ値が大きくなるようなリストを 生成する場合、Perlでは楽ができます。下記の@data1と@data2、 @data3と@data4は同じ結果になります。

@data1 = (1, 2, 3, 4, 5);
@data2 = (1 .. 5);

@data3 = (2.5, 3.5, 4.5, 5.5);
@data4 = (2.5 .. 5.5);

上記の@data3@data4でも同様)には 4つの要素が入っていて、それぞれの要素は下記のように表現されます。

要素 表現
0番目 $data3[0] 2.5
1番目 $data3[1] 3.5
2番目 $data3[2] 4.5
3番目 $data3[3] 5.5

特に最初の要素$data3[0]のように書く事は、 C言語でも共通ですし、忘れないでください。

演習3-1
下記のスクリプトをkadai3-1.plとして書き、実行結果を確認せよ。

#!/usr/bin/perl

@name = ('飯沼', '岩橋', '菊池', '吉田');
print "@name\n";

@data1 = (1, 2, 3, 4, 5);
for ($i = 0; $i < 5; $i++){
    print "\$data1[$i]= $data1[$i] \n";
}

@data2 = (1 .. 5);
for ($i = 0; $i < 5; $i++){
    print "\$data2[$i]= $data2[$i] \n";
}

配列の要素数と要素の末尾への追加と削除 - pop, push -

配列の要素数を調べるのは簡単です。下記の@nameという配列の 要素数を$lengthという変数に入れるとすると、

@name = ('飯沼', '岩橋', '菊池', '吉田');
$length = @name;

とするだけです。すると、$lengthには4という値が入ります。

この@nameという配列に新たに'河合'という要素を 追加したい場合を想定しましょう。

  1. 現在の要素数を利用する場合
    @nameの要素数が4つとわかっている場合、 5番目の要素として下記のように追加できます。
    $name[4] = '河合';
  2. 現在の要素数を利用しない場合1
    @name = (@name, '河合');
  3. 現在の要素数を利用しない場合2 (pushを利用)
    push @name, '河合';

このついでに、配列の末尾の要素を削除したい場合、

例1: pop @name;
例2: $delete_name = pop @name;

のようにします。例1の方法では単に削除するだけですが、 例2の方法では削除した要素を変数$delete_nameに入れています。 popを利用するとこのような使い方もできます。

演習3-2
下記のスクリプトをkadai3-2.plとして書き、実行結果を確認せよ。

#!/usr/bin/perl

@name = ('飯沼', '岩橋', '菊池', '吉田');

# 要素の追加
$name[4] = '河合';
print "@name\n";

# 要素の削除
pop @name;
print "@name\n";

# 要素の追加
@name = (@name, '河合');
print "@name\n";


# 要素の追加
push @name, '河合';
print "@name\n";

配列の先頭への追加と削除 - shift, unshift -

今度は、'河合'という要素を、@nameという 配列の先頭に新たに追加したい場合を想定しましょう。 2通りの方法があります。

@name = ('河合', @name);
unshift @name, '河合';

今度は、先頭の要素を削除するには、

例1: shift @name;
例2: $delete_name = shift @name;

とします。popのときと同様、例2では削除した要素を変数 $delete_nameに入れています。

配列の任意の要素への操作 - splice -

これまでに、配列の末尾への操作には、push, pop, 配列の先頭には、 shift, unshiftという関数を紹介しました。これらを統一的に 表現できるのが、spliceです。 下記の3通りの方法の方法を紹介します。

  1. splice (対象配列, 配列での位置, 削除する要素数)
    単に配列の一部を削除する方法です。下記の例を見てください。
    @name = ('飯沼', '岩橋', '菊池', '吉田');
    @delete_name = splice (@name, 1, 2);
    print "\@name = @name\n";
    print "\@delete_name = @delete_name\n";
    (実行結果)
    @name = 飯沼 吉田
    @delete_name = 岩橋 菊池
  2. splice (対象配列, 配列での位置)
    配列のある要素から最後までを削除する方法です。下記の例を見てください。
    @name = ('飯沼', '岩橋', '菊池', '吉田');
    @delete_name = splice (@name, 1);
    print "\@name = @name\n";
    print "\@delete_name = @delete_name\n";
    (実行結果)
    @name = 飯沼
    @delete_name = 岩橋 菊池 吉田
  3. splice (対象配列, 配列での位置, 削除する要素数, 追加するリスト)
    配列の一部を削除し、その削除されたところに別のリスト(配列)を 挿入する方法です。削除する要素数と追加する要素数は一致する 必要はありません。下記の例を見てください。
    @name = ('飯沼', '岩橋', '菊池', '吉田');
    @add_name = ('河合', '関本', '田中');

    @delete_name = splice (@name, 1, 2, @add_name);
    print "\@name = @name\n";
    print "\@delete_name = @delete_name\n";
    (実行結果)
    @name = 飯沼 河合 関ヒ[ 田中 吉田
    @delete_name = 岩橋 菊池

演習3-3
上記の例1から例3までをkadai3-3.plとして一つのスクリプトに書き、 実行結果を確認せよ。

配列の連結 - join -

joinを使うことで、配列の各要素を連結して1つの文字列にできます。 連結の仕方も下記の例のように指定できます。

@name = ('飯沼', '岩橋', '菊池', '吉田')
print join ('+', @name), "\n";
(実行結果)
飯沼+岩橋+菊池+吉田
@name = ('飯沼', '岩橋', '菊池', '吉田')
print join (',', @name), "\n";
(実行結果)
飯沼,岩橋,菊池,吉田

文字列のリスト化 - split -

joinとは逆に、splitを使うことで、1つの文字列を分割してリスト化し、 配列に入れて様々な操作ができるようになります。下記の例を見てください。

例: , を区切りに分割する場合

$str = '飯沼,岩橋,菊池,吉田';
@name = split(/,/, $str);
print "@name\n";

for ($i=0; $i<@name; $i++) {
  print "$name[$i]\n";
}
(実行結果)
飯沼 岩橋 菊池 吉田
飯沼
岩橋
菊池
吉田

演習3-4
下記のスクリプトをkadai3-4.plとして書き、実行結果を確認せよ。

#!/usr/bin/perl

@name = ('飯沼', '岩橋', '菊池', '吉田');
$str = join (',', @name);
print "$str\n";

@name = split(/,/, $str);
for ($i=0; $i<@name; $i++) {
  print "$name[$i]\n";
}
(実行結果)

飯沼 岩橋 菊池 吉田
飯沼
岩橋
菊池
吉田

配列の順番の逆転 - reverse -

reverseは、文字どおり配列の要素を逆順にします。

@name = ('飯沼', '岩橋', '菊池', '吉田')
@reverse_name = reverse(@name);

とすると、配列@reverse_nameには、配列@nameの要素が逆順で入れられます。

配列の要素の並び替え - sort -

sortは、文字列をASCIIコード順に並び替えます。

例1:アルファベットの場合

@name = ('kikuchi', 'iwahashi', 'yoshida', 'iinuma');
@sort_name = sort @name;
print "@name\n";
print "@sort_name\n";
(実行結果)

kikuchi iwahashi yoshida iinuma
iinuma iwahashi kikuchi yoshida

例2:日本語の場合

@name = ('飯沼', '岩橋', '菊池', '吉田');
@sort_name = sort @name;
print "@name\n";
print "@sort_name\n";
(実行結果)

飯沼 岩橋 菊池 吉田
岩橋 菊池 吉田 飯沼

例3:数字の場合 :文字列として評価されてソートされる

@num = (21, 9, 92, 12, 132, 5, 56);
@sort_num = sort @num;
print "@num\n";
print "@sort_num\n";
(実行結果)

21 9 92 12 132 5 56
12 132 21 5 56 9 92

例4:数字の場合 :きちんと数字として評価されてソートされる方法

@num = (21, 9, 92, 12, 132, 5, 56);
@sort_num = sort {$a <=> $b} @num;
print "@num\n";
print "@sort_num\n";
(実行結果)

21 9 92 12 132 5 56
5 9 12 21 56 92 132

演習3-5
上記の例1から例4までをkadai3-5.plとして一つのスクリプトに書き、 実行結果を確認せよ。

演習3-6
「21:53:08」のような時刻の文字列が存在すると仮定する。この文字列を 分解して変数に代入した結果、「21時53分08秒」と表示させたい。 どのように処理すればいいだろうか?

演習3-7
演習3-5の例4では、データを昇順(小さい順に並べること)でソート された。今、同じデータを降順(大きい順に並べること)でソート したい。どのように処理すればいいだろうか?

演習3-8

$line0='20,23,24';
$line1='32,42,21';
$line2='29,42,52';

というような、数字がカンマで区切られた文字列、$line0, $line1, $line2とい う変数が存在すると仮定する。この文字列を分解して数字を取出し、下記のよう に1番目、2番目、3番目の数字の和を表示させたい。 どのように処理すればいいだろうか?

(実行結果)
20,23,24
32,42,21
29,42,52
sum:
81,107,97

[Perl講座] [須崎純一トップページ]
須崎純一 京都大学大学 工学研究科都市環境工学専攻 環境情報学講座