第3章 リストと配列

3-1. リストと配列とは

リストとは、スカラーに順番をつけて並べたもので、そのリストの中でのスカラーの位置によって自由にアクセスすることができます。 そして、このリストを変数にしたものを配列といいます。
ポイント
「リスト」とは「データ」のことで、「配列」とはその「変数」を意味します。
配列の名前は、@ (アットマーク) + 英字1文字から始まり、それ以降は数字、英字およびアンダースコア ( _ ) を用いることができます。 また大文字と小文字が区別されますので、たとえば @a と @A は別物として扱われます。
変数名に使用できる文字
@abc123 変数名として使用可能。
@123abc 数字から始まることはできない。
@abc_123 アンダースコアは使用可能。
@abc-123 ハイフンは使用することはできない。
pagetop

3-2. 配列演算子

配列には、数値や文字列を代入することができます。
構文例 内容
@x = (1, 2, 3); @x に 1, 2, 3 をこの順序で代入(数値)
@y = ("apple", "orange"); @y に apple と orange をこの順序で代入 (文字列)
@z = ($a, $b, $c); @z に $a, $b, $c をこの順序で代入 (変数)
変数で構成されたリストに対して、リスト値を代入することができます。
構文例 内容
($x, $y, $z) = (1, 2, 3); $x, $y, $z にそれぞれ 1, 2, 3 を代入
($a, $b) = ("banana", "melon"); $a に banana を、$b に melon を代入
($a, $b) = ($b, $a); $a と $b の値を入れ換え
配列の中の各要素は、$配列名 [ 添え字 ] という形式で表すことができます。
配列の添え字は 0 から始まります。 したがって、配列の1番目から3番目の要素にアクセスするには、0 から 2 までを添え字として使用することになります。
以下の表の場合、パターン1とパターン2は、まったく同じ意味になります。
パターン1
@fruit = ("apple", "orange", "banana");
パターン2
$fruit[0] = "apple";
$fruit[1] = "orange";
$fruit[2] = "banana";
配列の各要素には、添え字を指定することで、以下のようにしてアクセスすることができます。
@fruit = ("apple", "orange", "banana");
print "$fruit[1]\n";
>  orange
配列末尾の要素の添え字は、$#変数名 という変数で表すことができます。
@fruit = ("apple", "orange", "banana");
print "$fruit[$#fruit]\n";
>  banana
配列の個数は、左辺のスカラー変数に代入することができます。
@fruit = ("apple", "orange", "banana");

# 配列の個数
$num = @fruit;

print "この配列の要素は$num個あります。\n";
>  この配列の要素は3個あります。
以下のようにして、配列に代入し要素を追加することができます。
@fruit = ("apple", "orange", "banana");

# 要素の末尾に追加
@fruit = (@fruit, "grape");

print "@fruit\n";
>  apple orange banana grape
pagetop

3-3. 配列関数

配列を操作するための関数として、次のような関数が用意されています。
関数 内容
push 配列の末尾へ要素を追加
pop 配列の末尾の要素を削除
unshift 配列の先頭へ要素を追加
shift 配列の先頭の要素を削除
reverse 配列の順序を逆順にする
sort 配列の順序をソートする
1. push
配列の末尾へ要素を追加します。
@char = ("A", "B", "C");
push(@char, "D");

print "@char\n"; 
>  A B C D 
2. pop
配列の末尾の要素を削除します。
@char = ("A", "B", "C");
pop(@char);

print "@char\n"; 
>  A B 
3. unshift
配列の先頭へ要素を追加します。
@char = ("A", "B", "C");
unshift(@char, "D");

print "@char\n"; 
>  D A B C 
4. shift
配列の先頭の要素を削除します。
@char = ("A", "B", "C");
shift(@char);

print "@char\n"; 
>  B C 
5. reverse
配列の順序を逆順にします。
@char = ("A", "B", "C");
@char = reverse(@char);

print "@char\n"; 
>  C B A 
6. sort
文字列、数値および昇順、降順によって4パターンのソートが存在します。
(1) 文字列としてソート(昇順)
@char = ("C", "A", "D", "B");
@char = sort(@char);

print "@char\n"; 
>  A B C D
(2) 文字列として逆ソート(降順)
@char = ("C", "A", "D", "B");
@char = sort{ $b cmp $a } @char;

print "@char\n"; 
>  D C B A
(3) 数値としてソート(昇順)
@char = (3, 1, 4, 2);
@char = sort { $a <=> $b } @char;

print "@char\n";
>  1 2 3 4
(4) 数値として逆ソート(降順)
@char = (3, 1, 4, 2);
@char = sort { $b <=> $a } @char;

print "@char\n";
>  4 3 2 1
pagetop

3-4. クォート構文

リストを記述する際の便利な書き方に、「単語のクォート構文」があります。
この構文を使うと、カッコの間にある空白以外の部分からリストが生成されます。
例えば、次のような配列の記述があったとします。
@week = ('Sun', 'Mon', 'Tue', 'Wed');
クォート構文を使えば、次のように書くことができます。
@week = qw(Sun Mon Tue Wed);
各要素の間は、空白以外に、タブや改行で区切っても構いません。
@week = qw(
	Sun
	Mon
	Tue
	Wed
	);
ちなみに、クォート構文の場合、上記のように ( ) ばかりではなく、他の記号( !, /, #, { }, [ ] など )を使っても構いません。
@week = qw!Sun Mon Tue Wed!;
pagetop

3-5. スライス

スライスとは、同じ配列から取り出した要素からなるリストへアクセスする表記法のことです。
たとえば、次のような配列があります。
@name = qw(mike fred kent peter);
1番目の要素と2番めの要素にアクセスするには、添字を使って次のように書くことができます。
($name[0], $name[1])
これをスライスを使えば、次のように書くことができます。
@name[0,1]
スライスの場合は、$ではなく、@が先頭に付いていることに注意してください。これは1つの要素(スカラー変数)に対する操作ではなく、配列の部分集合から配列変数を作成する操作のためです。
以下に例を見て行きましょう。
コード例-1 (任意の要素を取り出して記述)
@name = qw(mike fred kent peter);

print "@name[1,2]\n"; # 2番目と3番目を書き出す
>  fred kent
コード例-2 (任意の要素を入れ替える)
@name = qw(mike fred kent peter);

@name[0,1] = @name[1,0]; # 1番目と2番目を入れ替え
print "@name\n";
>  fred mike kent peter
コード例-3 (任意の要素を置き換える)
@name = qw(mike fred kent peter);

@name[0,1,2] = @name[1,1,1]; # 1〜3番目を全て2番目にする
print "@name\n";
>  fred fred fred peter
コード例-4 (任意の要素を置き換える)
@name = qw(mike fred kent peter);

@name[2,3] = qw(joe lee); # 2,3番目を他に置き換える
print "@name\n";
>  mike fred joe lee
pagetop

3-6. chomp関数

chomp関数は、スカラー変数ばかりではなく、配列に対しても使用できます。
引数に配列を指定することで、その配列の全ての要素から、末尾の改行を取り除くことができます。
@color = ("blue\n", "green\n", "red");
chomp(@color);

print "@color\n";
>  blue green red
pagetop

3-7. 多次元配列

配列は、多次元に展開させることができます。配列の中に、さらに配列を作ります。
例を見ながら説明してみましょう。以下の配列は、いわゆる二次元配列になります。
@list = (
	['a', 'b', 'c'],
	['d', 'e', 'f'],
	['g', 'h', 'i'],
);
2行目の ['a', 'b', 'c'] が1番目要素ですが、その要素の中にはさらに ('a', 'b', 'c') という配列が定義されています。
このように、配列を角括弧(ブラケット)で、ハッシュを波括弧(ブレース)で定義することをリファレンスといいます。
読み方 記述 内容
角括弧(ブラケット) [ ] リファレンスで配列を意味します
波括弧(ブレース) { } リファレンスでハッシュを意味します
上記の@listにて、角括弧の1行すべてがスカラー(文字列)だと解釈すれば、分かりやすいかもしれません。
ただし、スカラーといっても、実体は配列です。 (ちょっと複雑かも
配列@listにおいて、1番目の要素の中の、さらに1番目の要素である「a」にアクセスするには、添字を使用して次のとおり記述します。
@list = (
	['a', 'b', 'c'],
	['d', 'e', 'f'],
	['g', 'h', 'i'],
);

print "$list[0][0]\n";
>  a
リファレンスを使って、1番目の要素(配列)にアクセスするには、次のように記述することができます。
@list = (
	['a', 'b', 'c'],
	['d', 'e', 'f'],
	['g', 'h', 'i'],
);

print "@{$list[0]}\n";
>  a b c
要素ごとに展開表示(配列単位に全て)させるには、次のように記述します。
@list = (
	['a', 'b', 'c'],
	['d', 'e', 'f'],
	['g', 'h', 'i'],
);

foreach $tmp (@list) {
	print "@{$tmp}\n";
}
>  a b c
>  d e f
>  g h i
さらに、1つ1つの要素を全て展開させるには、次のように記述します。
@list = (
	['a', 'b', 'c'],
	['d', 'e', 'f'],
	['g', 'h', 'i'],
);

foreach $tmp1 (@list) {
	foreach $tmp2 (@{$tmp1}) {
		print "$tmp2\n";
	}
}
>  a
>  b
>  c
>  d
>  e
>  f
>  g
>  h
>  i
もう少し続けましょう。
@listへ要素を(二次元配列として)追加してみます。
@list = (
	['a', 'b', 'c'],
	['d', 'e', 'f'],
	['g', 'h', 'i'],
);

# 末尾の配列に追加
push(@list, ['j','k','l']);

# 末尾表示
print "@{$list[3]}\n";
>  j k l
特定の要素(二次元配列)の中に、要素を追加してみましょう。
@list = (
	['a', 'b', 'c'],
	['d', 'e', 'f'],
	['g', 'h', 'i'],
);

# 1番目の要素(二次配列)に要素を代入
push(@{$list[0]}, 'x');

# 1番目の要素を配列展開
print "@{$list[0]}\n";
>  a b c x
pagetop