関数順 インデックス
目的別 インデックス

構文
 
 sort サブルーチン名 ソート対象
 sort 処理ブロック ソート対象
 sort ソート対象

返り値
 
 ソート対象をソートした結果のリスト

説明

  • ソート対象のリストをソートして結果をリストで返します。
  • 「sort ソート対象」の形式の場合,ソート対象の中身を文字列として比較して昇順にソートした結果を返します。
  • 「sort 処理ブロック ソート対象」の形式の場合,処理ブロックの中でソートの方法を指定することができます。
  • 「sort サブルーチン名 ソート対象」の形式の場合,サブルーチン名という名前の関数でソートの方法を指定することができます。
  • 処理ブロック,サブルーチン名どちらの形式でも$aと$bを使って二つの要素の大小比較を行います。

使用例

配列@hogeをソートする
#!/usr/bin/perl
use strict;
use warnings;

my @hoge = ('foo', 'bar', 'baz');

my @items = sort @hoge;

foreach my $item (@items) {
  print $item, "\n";
}
配列@hogeをソートする
#!/usr/bin/perl
use strict;
use warnings;

my @hoge = ('foo', 'bar', 'baz');

my @items = sort { $a cmp $b } @hoge;

foreach my $item (@items) {
  print $item, "\n";
}
配列@hogeをソートする
#!/usr/bin/perl
use strict;
use warnings;

my @hoge = ('foo', 'bar', 'baz');

my @items = sort compare @hoge;

foreach my $item (@items) {
  print $item, "\n";
}

sub compare {
  return $a cmp $b;
}
※上記例で出てきたcmpは文字列比較演算子で,左側が大きい場合に1,左右等しい場合に0,右側が大きい場合に-1を返します。

配列@hogeを逆順にソートする(reverseを使用)
#!/usr/bin/perl
use strict;
use warnings;

my @hoge = ('foo', 'bar', 'baz');

my @items = reverse sort @hoge; 
# ソートした結果を逆順にしている

foreach my $item (@items) {
  print $item, "\n";
}
配列@hogeを逆順にソートする(比較方法を指定)
#!/usr/bin/perl
use strict;
use warnings;

my @hoge = ('foo', 'bar', 'baz');

my @items = sort { $b cmp $a } @hoge; 
foreach my $item (@items) {
  print $item, "\n";
}
配列@hogeの要素を数値比較してソートする
#!/usr/bin/perl
use strict;
use warnings;

my @hoge = (23, 1, 320, 10, 953, 8);

my @items = sort { $a <=> $b } @hoge;

foreach my $item (@items) {
  print $item, "\n";
}
配列@hogeの要素を辞書順(大文字/小文字の区別をせずに)でソートする
#!/usr/bin/perl
use strict;
use warnings;

my @hoge = ('apple', 'lemon', 'orange', 'Cookie', 'Strowberry', 'BANANA');

my @items = sort { lc $a cmp lc $b } @hoge;

foreach my $item (@items) {
  print $item, "\n";
}
カレント・ディレクトリ配下のファイルをファイル・サイズ順にソートして表示する
#!/usr/bin/perl
use strict;
use warnings;

my $dir = '.'; # 対象ディレクトリ

my @files = ();
opendir my $dh, $dir or die "$!:$dir";
while (my $path = readdir $dh) {
  next unless -f $path; # ファイル以外は除外
  push @files, sprintf("%s/%s", $dir, $path);
}
closedir $dh;

my @items = sort { -s $a <=> -s $b } @files; 
# -sでファイルサイズを取得する

foreach my $item (@items) {
  print $item, "\n";
}
※上記例では比較を{ -s $a <=> -s $b }のように行っています。 この方法では比較の度にファイルサイズの取得を行うため,ソートが完了するまでに同じファイルのサイズを何回も取得することになります。 性能に問題が発生するようであれば,ファイル・サイズの取得を各要素につき1回だけ行う方法もあります。 次の用例は一般にシュワルツ変換と呼ばれている方法です

カレント・ディレクトリ配下のファイルをファイル・サイズ順にソートして表示する(シュワルツ変換)
#!/usr/bin/perl
use strict;
use warnings;

my $dir = '.'; # 対象ディレクトリ

my @files = ();
opendir my $dh, $dir or die "$!:$dir";
while (my $path = readdir $dh) {
  next unless -f $path; # ファイル以外は除外
  push @files, sprintf("%s/%s", $dir, $path);
}
closedir $dh;

my @items = 
  map { $_->[0] } 
# 元のデータのみを取り出す

  sort { $a->[1] <=> $b->[1] } 
# 比較用のデータを使ってソート

  map { [$_, -s $_] } 
# 元のデータと比較用のデータの組を作成
  @files;

foreach my $item (@items) {
  print $item, "\n";
}
配列@itemsの要素をnameで比較してソートする。nameの値が同じ場合はさらにageで比較してソートする
#!/usr/bin/perl
use strict;
use warnings;

my @person = (
  { name => 'sato',   age => 50, no => 1 },
  { name => 'suzuki', age => 23, no => 2 },
  { name => 'takagi', age =>  4, no => 3 },
  { name => 'baba',   age => 10, no => 4 },
  { name => 'suzuki', age => 19, no => 5 },
  { name => 'suzuki', age => 32, no => 6 },
);

my @items = sort {
  $a->{name} cmp $b->{name} 
# nameで比較

    ||                      
# 比較結果が0(等しい)の場合

  $a->{age} <=> $b->{age}   
# ageで比較

} @person;

foreach my $item (@items) {
  printf "no(%d) name(%s) age(%d)\n", $item->{no},
$item->{name}, $item->{age}; }
※比較のためのキーが複数ある場合は条件と条件を,||でつなぐと見やすく書くことができます