Search A.I.
Menu
ホーム

メールマガジン ホームページプログラミングテク

Windowsテク
Javaアプレット サンプル
Java Q & A
JavaScript Q & A
Perl Q & A
Perl レッスン
PHP レッスン
PHPテク
MS-DOS コマンド集
UNIX コマンド集
SQL コマンド集
SEの基礎講座
WEBシステム開発受注します
]無料フォームメール送信サービス
リンク集
Perl レッスン

1. Perl の基礎
2. Perlの文法、条件式
3. Perlの文法、条件式 - 続き
4. 配列について
5. ハッシュ配列について
6. Perlの基礎 - 続き
7. 関数について
8. 関数について - 続き
9. 文字列操作関数
10. 配列操作関数
11. ファイル操作
12. ファイル操作 - 続き
13. パラメータの受け渡し
14. クッキーについて
15. 総合練習
16. メール送信
17. ファイルアップロード
18. パッケージの使用方法
19. MySQL
20. MySQL - 続き(1)
21. MySQL - 続き(2)
22. PostgreSQL
23. 総合練習
24. 総合練習解答



10. 配列操作関数

今日は、配列操作関数について、ご説明いたします。

■配列操作の関数
配列を操作するための、便利な関数をご紹介します。

join($str1, @ary) 配列を、$str1区切りの文字列に連結します。
split(/パターン/, $str1) 文字列をパターンで区切った配列にします。
sort(@ary) 配列をソートします。
reverse(@ary) 配列の順番を逆に並べ替えます。
push(@ary, $val) 配列の末尾に$valを加えます。
pop(@ary) 配列の最後の要素を取り出し、その要素を削除します。
unshift(@ary, $val) 配列の先頭に$valを加えます。
shift(@ary) 配列の先頭の要素を取り出し、その要素を削除して詰めます。

配列の操作関数は他にもありますが、よく使用されるのは、上記のものが多いです。

以下にサンプルを記述します。

-----------------------------------------------------------------
$path = '/usr/local/bin/perl';

# "/"の間の文字列を要素とする配列を作成
@ary = split(/\//, $path); # @ary = ('', 'usr', 'local', 'bin', 'perl')

# 配列をABC順にソート
@ary = sort(@ary); # @ary = ('', 'bin', 'local', 'perl', 'usr')

# 配列の順番を逆に並べ替え
@ary = reverse(@ary); # @ary = ('usr', 'perl', 'local', 'bin', '')

# 配列の最後の要素を削除
pop(@ary); # @ary = ('usr', 'perl', 'local', 'bin')

# 配列の末尾に追加
push(@ary, 'path'); # @ary = ('usr', 'perl', 'local', 'bin', 'path')

# 配列の先頭に追加
unshift(@ary, 'test'); # @ary = ('test', 'usr', 'perl', 'local', 'bin', 'path')

# 配列の先頭を削除
shift(@ary); # @ary = ('usr', 'perl', 'local', 'bin', 'path')

# 配列を","で区切った文字列に変換
$str = join(",", @ary); # $str = "usr,perl,local,bin,path"
-----------------------------------------------------------------

split()関数は、文字列を指定した区切り文字で分解し、配列を作成します。
区切り文字は、第1引数で指定しますが、前回やったパターンマッチの書式に
なります。サンプルでは、"/"文字で区切って分解しています。最初の文字が
"/"ですので、配列の最初の要素は、空文字となります。

sort()関数は、順番を並び替えます。基本的には文字コード順になるので、
日本語でもひらがな→カタカナ→漢字の順にうまくいくはずです。逆順に
ソートしたい場合は、

@ary = reverse(sort(@ary));

のようにします。

reverse()関数は、現在の配列を逆に並び替えます。サンプルのように、
空文字がある場合は、最後に移動されます。

pop()関数は、配列の最後の要素を取り出し、削除します。サンプルの場合は
空文字を取り出していますが、pop()の戻り値で最後の要素が返ってきています。

push()関数は、pop()の逆で、配列の末尾に要素を追加します。要素数は 1 つ
増えます。

unshift()関数は、配列の先頭に要素を追加します。もともとの先頭の要素は
削除されず、要素数が 1 つ増える形になります。

shift()関数は、unshift()の逆で、配列の先頭の要素を削除して、詰めます。

join()関数は、配列を好きな区切り文字で、文字列に連結させることができます。
サンプルの場合は、","で 1 つの文字列につなげています。

■ハッシュ配列操作関数
ハッシュ配列を操作するための関数もいくつかあります。

keys(%hash) ハッシュ配列%hashのキー値を配列で返します。
values(%hash) ハッシュ配列%hashの値を配列で返します。
each(%hash) ハッシュ配列%hashのキー値、値を返します。

使用方法のサンプルを記述します。

-----------------------------------------------------------------
%hash = ('name'=>'Jun Takayama', 'mail'=>'info@searchai.jp');

@key = keys(%hash);
print @key;

@value = values(%hash);
print @value;

($a, $b) = each(%hash);
print $a;
print $b;
-----------------------------------------------------------------

keys()は、キー値の配列が返ってきますので、上のサンプルだと'name'、'mail'の
入った配列が出力されます。ただし、順番はランダムとなります。

values()は、ハッシュ値の配列ですので、'Jun Takayama'、'info@searchai.jp'の
入った配列が出力されます。ただし、順番はランダムとなります。

each()は、キー値とハッシュ値を 1 組返す関数ですので、'mail'、
'info@searchai.jp'の組が返されると思います。どの組が返されるかは、ランダムの
ようですので、通常はループで全ての値を取り出す時に使用します。

これらの関数をループで使用した例を以下に記述します。

-----------------------------------------------------------------
%hash = ('name'=>'Jun Takayama', 'mail'=>'info@searchai.jp');

foreach $key( keys(%hash) ) {
print $key;
}

foreach $value( values(%hash) ) {
print $value;
}

while ( ($a, $b) = each(%hash) ) {
print $a;
print $b;
}
-----------------------------------------------------------------

ここで、keys()やvalues()は、ハッシュ配列を順番にループさせるので、foreach文
を使用していますが、each()は、なぜか同じ組のものを取り出してしまうので、
while文を使用した方が良いようです。

 

★今日のまとめサンプルプログラム
-----------------------------------------------------------------
#! /usr/local/bin/perl

print "Content-type:text/html\n\n";

print << "END_OF_HTML";
<HTML>
<BODY>
END_OF_HTML

# 曜日のカンマ区切りの文字列
$week = "sun,mon,tue,wed,thu,fri,sat";

# 曜日を配列に格納
@week = split(/\,/, $week);

# 曜日を文字列に連結
print join(' | ', @week) . "<br>";

@ary = (50,28,72,17,32,81,7,66,97);

# 配列の最後に追加
push(@ary,49);

# 配列をソートする
@ary = sort(@ary);

# 配列の最後を取り出して表示
print pop(@ary) . "<br>";

# 配列の最初を取り出して表示
print shift(@ary) . "<br>";

# 配列の最初に挿入
unshift(@ary, 8);

# 文字列に連結して表示
print join(" ", @ary) . "<br>";

# ハッシュ配列の作成
$data{'name'} = "Jun Takayama";
$data{'mail'} = "searchai@zw.main.jp";

# keysを使用して値を取得
foreach $key ( keys(%data) ) {
print $key . "の値は" . $data{$key} . "<br>";
}

# eachを使用して値を取得
while ( ($key, $value) = each(%data) ) {
print $key . "の値は" . $value . "<br>";
}

print << "END_OF_HTML";
</BODY>
</HTML>

END_OF_HTML

exit;
-----------------------------------------------------------------

■解説
注意してほしいのは、配列に整数を格納してソートした場合、文字列として扱われて
ソートされている点です。つまり、66 より 7 の方が小さいですが、文字列として
考えた場合、最初の文字の'6'より'7'の方が大きいため、 66 の後に 7 がきます。

pop()やshift()は、配列の最後と最初を削除するだけでなく、戻り値として返って
きます。配列から取り出すというイメージです。

ハッシュ配列をループで取り出すという処理は、あまり実際のプログラムで必要な
ことはないので、頭の片隅に入れておく程度で結構です。

 

★課題
1. 以下の処理を行うプログラムを作成してください。

(1) 'sun;mon;tue;wed;thu;fri;sat'という文字列の";"を除いて配列に格納し、
さらに" : "で区切った文字列に連結し、出力する
(2) 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'という文字列の','を
除いて配列に格納し、アルファベットの逆順にソートする
(3) ('sun','mon','tue','wed','thu','fri','sat')という配列で、最初の'sun'を
一番最後に移動する処理
(4) ('name'=>'Ichiro Suzuki','mail'=>'mail@email.co.jp')というハッシュ配列の
ハッシュ値のみを取り出して出力する

 

★前回の課題の解答
1. 以下の処理を行うプログラムを作成してください。

(1) 'test@homepage.co.jp'の文字列から、"@"と最初の"."の間の文字列を出力する
(2) 現在日時を取得し、'2004年01月01日 00時00分00秒'の形式で出力する
(3) 'abc123'という文字列が、半角英数字のみかどうかを判定する
(4) 'test'、'TEST'、'Test'のどの文字がきても、'Test'に置換して出力する
(5) '100円'、'98765円'のような文字を、'\100'、'\98775'に置換して出力する

→下のサンプルを参照してください。

-----------------------------------------------------------------
#! /usr/local/bin/perl

require './test.pl';

print "Content-type:text/html\n\n";

print << "END_OF_HTML";
<HTML>
<BODY>
END_OF_HTML

# (1) 'test@homepage.co.jp'の文字列から、"@"と最初の"."の間の文字列を出力する

$mail= 'test@homepage.co.jp';
print substr($mail, index($mail, '@')+1, index($mail, '.')-index($mail, '@')-1) . "<br>";

# (2) 現在日時を取得し、'2004年01月01日 00時00分00秒'の形式で出力する

($sec,$min,$hour,$mday,$mon,$year) = localtime(time);
$year += 1900;
$mon++;
print sprintf("%04d年%02d月%02d日 %02d時%02d分%02d秒<br>", $year, $mon, $mday, $hour, $min, $sec);

# (3) 'abc123'という文字列が、半角英数字のみかどうかを判定する

$str = 'abc123';
if ($str =~ m/[0-9a-zA-Z]/) {
print "半角英数字のみ<br>";
}

# (4) 'test'、'TEST'、'Test'のどの文字がきても、'Test'に置換して出力する

$str = 'TEST';
$str =~ s/test/Test/i;
print $str . "<br>";

# (5) '100円'、'98765円'のような文字を、'\100'、'\98775'に置換して出力する

$price = "98765円";
$price =~ s/(\d+)円/\\$1/g;
print $price . "<br>";

print << "END_OF_HTML";
</BODY>
</HTML>

END_OF_HTML

exit;
-----------------------------------------------------------------

■解説
(1)は少し複雑ですが、substrの引数は、1:元の文字列、2:抜き出し開始の位置、
3:抜き出す文字数ですので、3 つ目の引数は、'.'の位置から'@'の位置を引くと、
長さが計算できます。しかし、これだけでは'.'も含まれてしまいますので、-1
します。

(5)も少し難しいですが、\d+で数字の連続した文字を検索します。'\'は特殊文字
ですので、エスケープします。$1は、\dでヒットしたものをそのまま出力します。




前の章へ 次の章へ


このエントリーをはてなブックマークに追加


OfficeLance

お問い合わせはこちらから