Perlを使ってエクセル表 (CSV) のデータを都道府県順に並べ替える方法を紹介します。

都道府県順の並べ替えの他、「役職名」や「支店順」に社員名簿を並び替えるなどの用途に応用できます。並べ替えの順番を外部ファイルに記録して、メンテナンスをしやすくする方法を紹介します。

Perl の並べ替えの基本

具体的なプログラミングを始める前に、まずは Perl の並べ替えの仕組みを説明します。Perl の並べ替えは sort 関数を使います。sort 関数の引数は配列です。
my @sorted = sort ('う', 'あ', 'い');
こうすると、@sorted には ('あ', 'い', 'う') が入ります。

sort の落とし穴


気をつけなければならないのは、sort は引数を全て文字列として扱うという事です。これは、右辺の配列が数値だった場合も同じです。

my @str = sort ('1', '2', '11', '10');
my @num = sort (1, 2, 11, 10);

この時 @str と @num の並べ替えの結果は同じになり、@str は配列 ('1', '10', '11', '2')、@num は (1, 10, 11, 2) になります。

なぜ11の後に2が来るのかと言うと、文字としては1を使っている11の方が先に来るからですね。

シングルクオートで囲っていない数字は、後で使う時に数値として認識される事を意味します。つまり、並べ替え時は文字列として比較し、結果としては元の数値を戻してくれるという事です。Perl らしい所です。

sort のカスタマイズ

右辺の配列を数値として並べ替えしたい時は、sort の後に大小判別のためのプログラムコードを指定します。
my @num_strict = sort {$a <=> $b} (1, 2, 11, 10);
こうすると、@num_strict には期待通り (1, 2, 10, 11) が入ります。

ここで出て来た $a、$b、<=> というのは sort のための特別の変数と演算子と呼ばれる記号です。$a と $b は並べ替え対象の一つ一つの要素を表し、<=> はそれぞれの要素を数値として比較する事を意味します。

<=> の左辺に $a があり右辺に $b がある時は、数値が小さい順に並べ替えが行われます。逆の場合は大きい順です。

また、<=> は数値として比較する事を指定する場合に使いますが、文字列として比較する場合はこの代りに cmp を使用します。

プログラムコードを一切指定しない sort は以下のものと等価です。

my @str = sort {$a cmp $b} ('1', '2', '11', '10');

逆に並べたい場合は、以下のようになります。

my @str_reverse = sort {$b cmp $a} ('1', '2', '11', '10');

この結果は ('2', '11', '10', '1') になります。

この sort に指定するプログラムブロックが役に立つのは、単純な $a、$b の比較だけでなくこの変数で式を作って比較ができる点です。

例えば「みかん」「いちご」「りんご」を好きな順番に並べ替えたいとします。

私の場合は「みかん」、「りんご」、「いちご」なので、例えばこんなハッシュを用意しておきます。

my %index = (
     'みかん' => 1,
     'りんご' => 2,
     'いちご' => 3,
);
ハッシュのキーが並べ替え対象とする要素、値の数値が好きな果物の順番です。このハッシュの値を、sort 関数の中で使うのです。

my @favorite = sort {$index{$a} <=> $index{$b}} ('いちご', 'みかん', 'りんご');

分かりますか?比較しているのは「いちご」や「みかん」の文字列そのものではなく、それらの文字列をキーとしたハッシュの値を比較しているのです。ハッシュは並べ替えの時だけ使われるので、@favorite
には ('みかん', 'りんご', 'いちご') が入ります。

次は:都道府県名でのエクセル並べ替えサンプルコード