« 「すぐわかるPerl」 7.9 splitとjoin | トップページ | 「すぐわかるPerl」 7.11 ユーザーのオリジナル関数 »

2008年7月 2日 (水)

「すぐわかるPerl」 7.10 リストコンテキストの

■<STDIN>を配列に代入する

@lines = <STDIN>;

こうすることで、標準入力の全行が配列に入る。

今まで使ってきたフィルター

while (<STDIN>){
print;
}

以下のように書き換えることもできる。

@lines = <STDIN>;
foreach(@lines){
print;
}

なお、printもリストコンテキストでは配列の要素を全部吐き出す。
基本のフィルターをこの観点から書き換えると

@lines = <STDIN>;
print @lines;

とも書けるし

print <STDIN>

と書いても同じ。
しかし、このままでは何の処理も挟めないためフィルターにならない。

■入力をソートして出力するフィルター

sortという関数は、配列を並べ替えたリストを返す。
特に指定しない限りは文字列として(辞書順に)昇順に並べ替える。
sortをはさんだフィルターは以下のようになる。

@lines = <STDIN>;
@sorted_lines = sort(@lines);
print @sorted_lines;

こうもかける。

@lines = <STDIN>;
print sort(@lines);

さらに短く

print sort(<STDIN>);

ちなみにreverseという関数は配列の順序をひっくり返した配列を出力する。
これを応用して、標準入力をひっくり返して出力するには

print reverse(<STDIN>);

この一行でいい。
・・・これはなにか美しさを感じるなぁ。うっとり。

sortについては指定することで並べ替えの論理を変えることが可能。

sort {$a cmp $b} 対象の配列 文字列比較、昇順(デフォルトと同じ)
sort {$b cmp $a} 対象の配列 文字列比較、降順
sort {$a <=> $b} 対象の配列 数値比較、昇順
sort {$a <=> $b} 対象の配列 数値比較、降順

{}の中には、ソートした結果が前に並ぶデータ$aと後ろに並ぶデータ$bが等しければ0
$aのほうが大きければ-1
$bのほうが大きければ1という三つの値を返す演算を入れる。

$a,$bは固定。
ただし、ブロック内のローカルな変数のため、ほかの場所でも$aや$bを利用することはできる。

<=>やcmpは比較の結果に応じて-1,0,1という三つの値を返す演算子。
<=>はその形から宇宙船演算子(spaceship operaor)といわれる・・・これは眉つばで聞いておこう。

■日付として昇順にソートする。

文字列の中に日付が現れる場合はどのようなパターンがあるか。

Apr 7th ,1984
the 7th of April 1984
4/7/1984
1984/4/7

考えていくときりがないので、いかにルールを決める。
・非数字に囲まれた4桁の数字は西暦
・Jan,Febという文字列が大文字、小文字関係なくあったら、それを月名と判断。
・ない場合には、いちばん最初の日数字に囲まれた二桁以下の数字を月名と判断する。
・Jan,Febが見つかった場合はいちばん最初の、見つからなかった場合には2番目の非数字に囲まれた二桁以下の数字を月名と判断する。
・上記の論理に当てはまらないものは一番後ろにソートする。

|

« 「すぐわかるPerl」 7.9 splitとjoin | トップページ | 「すぐわかるPerl」 7.11 ユーザーのオリジナル関数 »

Perl」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)


コメントは記事投稿者が公開するまで表示されません。



トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/214806/41711865

この記事へのトラックバック一覧です: 「すぐわかるPerl」 7.10 リストコンテキストの:

« 「すぐわかるPerl」 7.9 splitとjoin | トップページ | 「すぐわかるPerl」 7.11 ユーザーのオリジナル関数 »