Perl:配列・連想配列を条件に基づいてソート(sort)
技術ドキュメント目次 -> Perl -> 配列・連想配列を条件に基づいてソート(sort)本技術ドキュメントは、2002~2004年頃に作成したものが多いです。
内容が古くなっていることもあるかと思いますが、ご了承ください。
【低価格SSL証明書】弊社運営の低価格SSL証明書販売サイト、翌月末払いなど請求書払いも可能。
◆ sortとは
sort 関数は、リスト(配列。連想配列のキー一覧を keys 関数で取得したものも配列。)を
条件に基づいてソートする関数になります。
配列の並び順を変更したり、
連想配列のキー一覧をその連想配列の値に基づいて並び替えたりするときに便利です。
sort関数の構文は次のとおりです。
sort LIST sort BLOCK LIST sort SUBROUTINE LIST |
◆ sortの使用例(ソート条件はデフォルトで)
sort の一番簡単な使用例としては、例えば次のようなサンプルコードを用意して、
my @list = ('Taro', 'Jiro', 'Saburo'); @list = sort @list; for my $val (@list) { print $val . "\n"; } |
それを実行すると次のような出力が行われます。
配列の並び順がABC順でソートされたことが確認できます。
$ perl test.pl Jiro Saburo Taro $ |
また、sort 関数はデフォルトではABC順の比較を用いるため、
次のようなサンプルコードを用意すると、
my @list = (1, 22, 101, 55, 402); @list = sort @list; for my $val (@list) { print $val . "\n"; } |
次のような出力が行われます。
配列の並び順が、たとえその値が数値であったとしても、ABC順でソートされていることが確認できます。
$ perl test.pl 1 101 22 402 55 $ |
◆ sortの使用例(ソート条件を自分で指定)
上記の例ではソート条件がデフォルトのABC比較になっていましたので、数値が数値としてソートされることはありませんでしたが、
そのコードを次のように変更すると、
my @list = (1, 22, 101, 55, 402); @list = sort {$a <=> $b} @list; for my $val (@list) { print $val . "\n"; } |
次のような出力が行われます。
$ perl test.pl 1 22 55 101 402 $ |
sort 関数の後に指定した {$a <=> $b} というブロックがポイントで、
この指定を行うことによって数値で比較されるようになったのです。
なお、ここで、{$a cmp $b} と記述すると、デフォルトと同じ動作で
ある文字列でのソートが行われます。
また、ここで、{$a <=> $b} ではなく {$b <=> $a} と指定をすると、
数値で比較されますが、結果は逆順にソートされて大きいものが先に
くるように並び替えられます。
◆ 連想配列をソートする
連想配列の値を出力する方法として、よく次のような手法が持ちられるかと思います。
my %hash; $hash{Taro} = 80; $hash{Jiro} = 80; $hash{Saburo} = 90; $hash{Shiro} = 92; $hash{Goro} = 78; for my $key (keys %hash) { print $key . "=" . $hash{$key} . "\n"; } |
上記のコードを実行すると次のような出力がされますが、
この並び順はソートされていません。
Goro=78 Jiro=80 Taro=80 Saburo=90 Shiro=92 |
上記の並び順を連想配列のキーでソートするには次のように
keys関数の前に sort 関数を指定します。
my %hash; $hash{Taro} = 80; $hash{Jiro} = 80; $hash{Saburo} = 90; $hash{Shiro} = 92; $hash{Goro} = 78; for my $key (sort keys %hash) { print $key . "=" . $hash{$key} . "\n"; } |
上記の実行結果は次のようになります。
Goro=78 Jiro=80 Saburo=90 Shiro=92 Taro=80 |
また、連想配列の値の数値比較(大きなものが先)でまずはソートを行い、
値が同じであった場合にはキーの文字列比較(ABC順でAが先)でソートするには、
次のようなコードになります。
(sort 関数の次の {} の指定の中に || で区切った複数の条件を指定すると、
前の条件から順番に評価され、前の条件で同点になった場合は、次の条件が評価されます)
my %hash; $hash{Taro} = 80; $hash{Jiro} = 80; $hash{Saburo} = 90; $hash{Shiro} = 92; $hash{Goro} = 78; for my $key (sort {$hash{$b} <=> $hash{$a} || $a cmp $b} keys %hash) { print $key . "=" . $hash{$key} . "\n"; } |
上記の実行結果は次のようになります。
Shiro=92 Saburo=90 Jiro=80 Taro=80 Goro=78 |
sort の {} のブロック内にもう少々複雑な指定を行ったりすることで、
CSVファイルを特定の項目値に基づいてソートするようなことも可能になります。
■ Perl についての他のドキュメント
- %SIGによるシグナルの制御
- CSV等区切り文字で連結されたデータを操作(joinとsplit)
- Digest::MD5
- Digest::SHA1
- localtime()やgmtime()をスカラーで評価
- 正規表現において // の代わりに || を使用する
- 正規表現における () と (?:) の違い
- 配列・連想配列を条件に基づいてソート(sort)
■ 他のグループのドキュメント
Apache / Linux / FreeBSD / OpenSSL / Perl / HTTPプロトコル / Jakarta Tomcat / Java / NetBSD / Oracle / PostgreSQL / UNIX の C言語 / UNIX のコマンド / Windows / bind / システム運用TIPS