Array

last-modified: 17th/June/'01;
since: 1st/June/2001;

いままでは変数はひとつの値しか代入できませんでした。これをスカラー変数と呼びます。一方、スカラー・データをコンマで区切って並べたものをリストと呼びます。リストが代入されている変数はスカラー変数と区別して配列変数と呼び、スクリプトでは @ から始まります。コンピュータプログラムでは不可欠な役割を演じます。

次の例は print 函数の引数がリストになっています。

print ("Hello, world!", "\n");

リストの括弧は省略できますが、ほとんどの場合はつけておいたほうが無難でしょう。次のように書いても結構です。配列変数 @hello にリスト ("Hello, world!", "\n") が代入されています。

@hello = ("Hello, world!", "\n");
print "@hello";

引用符が二重引用符になっているので変数展開され、配列に代入されたリストが出力されます。

本稿では配列と、その書き下し表現であるリストに付いて紹介します。なお、配列やリストの個々のスカラー値は要素と呼びます。(詳しくは前節を参照ください。)

自作 grep

次のサンプルスクリプトは、コマンドラインからファイル名とパターンを入力して、ファイル内検索を行います。

実行コマンド例>>

% chmod +x grep.pl
% ./grep.pl PATTERN FILENAME FILENAME FILENAME

PATTERN にはパターンマッチする正規表現を入れてください。 FILENAME には検索対象のファイル名を入れてください。従って、コマンドライン引数は最低二個以上になります。

Perl では、コマンドライン引数は、配列 @ARGV に蓄えられます。従って、配列 @ARGV の要素は次のようになります;

@ARGV[0] = PATTERN;
@ARGV[1] = FILENAME;
@ARGV[2] = FILENAME;
@ARGV[3] = FILENAME;

Perl では配列のサイズは自動的に調整されるので、事前に宣言しておく必要はありません。

grep.pl>>

 1:
 2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
#!/usr/bin/perl
#上の行では、 Perl のパスを記述してください。
if (@ARGV < 2) {
  print "NO FILE!\n";
  exit;
} else {
  $pattern = shift(@ARGV);
  print "@ARGV\n";
  foreach $filename (@ARGV) {
    open(SEARCH, $filename);
    $counts = 0;
    while ($line = <SEARCH>){
      if($line =~ /$pattern/){
        $counts++;
        print "$filename($counts): $line\n";
      }
    }
    push(@score,$counts);
    close(SEARCH);
  }
  print "パターン:", $pattern, "\n";
  print "ファイル名:", "@ARGV", "\n";
  print "カウント数: @score\n";
}

3, 7, 9, 18 行目に注目してください。それぞれ配列特有の約束です。

[説明]

本節はまだ作成途中です。説明をもう少し分かりやすくしたいと思います。ご意見・ご感想をお寄せください。

foreach ループ

foreach 文は配列の繰り返しに用います。

foreach $value (@array) {
  ブロック
}

@array の第一要素から順番に変数 $value に代入し、ブロック内を実行します。配列の最後の要素に付いて終了すると、繰り返しが終了します。

@value は省略できますが、省略した場合は、標準変数 $_ が代わりに使われます。

for ループ、 while ループなど、他の繰り返し制御構造でも実現できますが、配列の場合は foreach ループが便利です。

# for ループでの実現例
for ($i = 0; $i < @array; $i++) {
  $value = $array[$i];
  ブロック
}

配列操作

スクリプトを作っていると、配列に要素を加えたり、取り出したり、接続したりしたい場合があります。このような配列操作の函数は沢山用意されていますが、ここではその一部を紹介します。

reverse

リストの並び順を逆にします。

@array = (a, b, c);	#リストコンテキスト
@new = reverse(@array);	# @new = (c, b, a)
$value = "string";		#スカラーコンテキスト
$new = reverse($value);	# $value = "gnirts"

リストの逆順で要素に参照する場合は、インデクスを負値にとっても結構です。

@array = (a, b, c);
	#$array[0] = a, $array[1] = b, $array[2] = c
	#$array[-1] = c, $array[-2] = b, $array[-3] = a

shift, pop

配列の最初か最後の要素を抜き出して、残りの要素を詰めます。

@array = (a, b, c, d);
$value = shift(@array);	#$value = a,  @array = (b, c, d)
$value2 = pop(@array);	#$value2 = d, @array = (b, c)

unshift, push

配列の最初か最後に要素を付け加えます。 shift, pop と逆の操作です。

@array = (a, b, c, d);
unshift(@array, e, f);	@array = (e, f, a, b, c, d)
push(@array, e, f);	@array = (a, b, c, d, e, f)

splice

shift, pop の拡張です。

配列の任意の場所から、任意個の要素を抜き出し、残りの要素を詰めます。また、抜き出す代わりに、他のリストに置換することも可能です。

#splice の基本書式
@new = splice(@array, インデクス, 個数, リスト);
	#@array に対して、「インデクス」の要素から「個数」分の要素を「リスト」で置換し、
	#置換された元の要素は @new に代入されます。
#splice の利用例
@array_old = @array;
@new = splice(@array, 2, 4, a, b, c);
	#@new = ($array_old[2], $array[3], $array[4], $array_old[5]),
	#@array = ($array_old[0], $array_old[1], a, b, c, $array[6])
#splice の利用例
@array = (a, b, c ,d);
@new = splice(@array, 1, 2, e, f);
	#@array = (a, e, f, d), @new = (b, c)

shift, pop, unshift, pushsplice でも実現できます。

[spliceshift, pop, unshift, push]
shift $value = shift(@array) $value = splice(@array, 0, 1)
pop $value = pop(@array) $value = splice(@array, $#array, 1)
unshift unshift(@array, a, b) splice(@array, 0, 0, a, b)
push push(@array, a, b) splice(@array, $#array, 0, a, b)

join, split

join はリストの要素間に区切り文字列を挿入して結合しスカラー値にします。 split はスカラー値を区切り文字列で切断して配列にします。 joinsplit は逆の働きをしますので、配列を join で結合したあとで split で配列に戻すことが出来ます。

#【join の基本書式】
$value = join("区切り文字列", 配列);
#join の利用例
$value = join(" ]:[ ", a, b, c);	#$value = "a ]:[ b ]:[ c"
#【split の基本書式】
@array = split(/正規表現/, 文字列);
#split の利用例
@array = split(/:/, "a ]:[ b ]:[ c");	#@array = ("a ]", "[ b ]", "[ c")
@array = split(/ ]:[ /, "a ]:[ b ]:[ c");	#@array = ("a", "b", "c")

例えば、 split はカンマ , で区切られた CSV データの各項を、配列要素として取り込むときに便利です。

@data = split(/,/, $line);

grep

指定された条件にマッチする要素を全て返します。 UNIX などではおなじみです。

#【grep の基本書式】
@array = grep(条件式, 配列)

条件式には通常の「式」に加えて、 /正規表現/ も使えます。

@return = grep($_ > 5, 3, 2, 8, 4, 1, 6, 7);
	#@array = (8, 6, 7)
@return = grep(/つ/, "つち", "あめ", "ほし", "かわ", "つき");
	#@array = ("つち", "つき")

条件式はブロックにしても結構です。

@return = grep{
	ブロック
}(@array);

sort

配列を文字列順に並べ替えます。 UNIX などではおなじみです。

#【sort の基本書式】
@array = sort 配列;

サブルーチンを作ることで、任意の並べ順にソートできるのですが、ここでは割愛します。


以上で配列の基本的な操作について終了します。次節では、ハッシュの使い方を紹介します。ハッシュとは、「連想配列」とも呼ばれるものです。配列では要素は 0 から始まる番号で参照していました。この番号はインデクスと呼ばれることもあります。ハッシュでは、番号の代わりに文字列で参照できます。

引き出しに番号がついている箪笥が配列で、名前がついている箪笥がハッシュです。

Copyright: SUGAI, Manabu. Since: 2001
FC2> モビット