特定の項目でソートする - Perl

この記事は2006年10月04日に書かれたものです。

以下のような配列がある時、2番目の項目で並べ替えがしたい。 単純に sort @array しただけではできない。

@array = ( '1,b,c'
             , '3,c,b'
             , '2,a,a'
);

ソート項目が数値の時にはorderByArrayNum、文字列の時にはorderByArrayStrをそれぞれ呼び出せば良い。配列そのものの値が変わるので、オリジナルを保存しておきたい場合には、必ずコピーを渡すこと。

サンプル

;#
;#特定の項目でソートする
;#
 
use strict;
 
{
  my @array = ( '1,c,A'
         , '3,b,B'
         , '2,a,C'
  );
 
  #-- 並べ替え(文字列) --#
  orderByArrayStr(
        \@array    #対象配列
         , 1    #ソートするキー(0,1, ... n)
         , 'ASC'  #ASC:昇順、DESC:降順
  );
 
  print "$_\n" foreach( @array );
  print "\n";
 
  #-- 並べ替え(数値) --#
  orderByArrayNum(
        \@array    #対象配列
         , 0    #ソートするキー(0,1, ... n)
         , 'DESC'  #ASC:昇順、DESC:降順
  );
 
  print "$_\n" foreach( @array );
  print "\n";
}
 
 
#----------------------
#数値ソート
#----------------------
sub orderByArrayNum{
  my $data = shift;      #配列の参照
  my $key = shift || 0;    #ソートするキー
  my $set = shift || 'DESC';  #昇順or降順
  my @tmp = ();
 
  #-- 一時配列にキーを取り出す --#
  @tmp = map {(split /,/)[$key]} @$data;
 
  #-- ソート開始 --#
  if( $set eq 'ASC' ){
    @$data = @$data[sort {$tmp[$a] <=> $tmp[$b]} 0 .. $#tmp];
  }
  else{
    @$data = @$data[sort {$tmp[$b] <=> $tmp[$a]} 0 .. $#tmp];
  }
 
}
 
 
#----------------------
#文字列ソート
#----------------------
sub orderByArrayStr{
  my $data = shift;      #配列の参照
  my $key = shift || 0;    #ソートするキー
  my $set = shift || 'DESC';  #昇順or降順
  my @tmp = ();
 
  #-- 一時配列にキーを取り出す --#
  @tmp = map {(split /,/)[$key]} @$data;
 
  #-- ソート開始 --#
  if( $set eq 'ASC' ){
    @$data = @$data[sort {$tmp[$a] cmp $tmp[$b]} 0 .. $#tmp];
  }
  else{
    @$data = @$data[sort {$tmp[$b] cmp $tmp[$a]} 0 .. $#tmp];
  }
 
}

実行結果

2,a,C
3,b,B
1,c,A
3,b,B
2,a,C
1,c,A

参考

関連書籍

chromatic, Damian Conw…
ISBN 4873113148
¥ 9,725

Joseph N. Hall, Joshua…
ISBN 4798139815
¥ 4,104

コメント

コメントを入力. Wiki文法が有効です:
Z Y T L C