ようこそゲストさん

Magical Diary, beta version

[Perl] 続・ソート

2007/07/20 20:09 HIRATA Yasuyuki

シュワルツ変換の代替

先日の記事 で、一時変数を利用する場合に比較して速度が低下すると書いたが、これは使用するメモリ量が多くなること、データ構造が若干に複雑になることに起因する。(とはいえ、比較のたびにコストが高い処理を行う場合を考えれば雲泥の差ではある。)

これを解決するためには、以下のように記述すればよい。

@files = qw[mami.txt emi.txt pelsia.txt yumi.txt];
@cmpkey = map { -f } @files;
@ordered = @files[sort {$cmpkey[$a] <=> $cmpkey[$b]} 0..$#files ];
print "@ordered\n";

この方法は perldoc (perlfaq4) でも紹介されている。(むしろ、シュワルツ変換の方が代替手段の扱い。)

複数のキーでソートする

以下では age で比較、同値だった場合には name で比較している。

@girls = ({name => "Morisawa Yu", age => 10},
          {name => "Pelsia", age => 11},
          {name => "Kaduki Mai", age => 11},
          {name => "Hanazono Yumi", age => 11},
          {name => "Shinohara Miho", age => 8});
@ordered = sort { $a->{age} <=> $b->{age} ||
                  $a->{name} cmp $b->{name} } @girls;
foreach my $x (@ordered) {
  print "$x->{name} $x->{age}\n";
}

演算子 <=>cmp は両辺の値が等しかった場合には 0 を返す。また、EXPR0 || EXPR1 は、

  • EXPR0 が真 ("0" または undef 以外) の場合、EXPR0
  • EXPR0 が偽 ("0" または undef) の場合、EXPR1

となる。これを利用して複数の条件でソートすることが可能である。


#  非公開コメント   

  • TB-URL(確認後に公開)  http://diary.asuka.net/012/tb/
© 2007 HIRATA Yasuyuki <yasu@asuka.net>, all rights reserved