« 配列,リストからある条件と一致した値を取出す (Perl, grep) | メイン | 1回のファイルオープンで読み書きを同時にしたい (Perl, file, read/write) »

カテゴリー:ソート(並べ替え) リスト(配列) 

特定の項目でソートする (Perl, リスト, 並べ変え)

このエントリーを含むはてなブックマーク  livedoorクリップ  特定の項目でソートする (Perl, リスト, 並べ変え)をdel.icio.usに追加  特定の項目でソートする (Perl, リスト, 並べ変え)をYahoo!ブックマークに追加  特定の項目でソートする (Perl, リスト, 並べ変え)をニフティクリップに追加

以下のような配列がある時、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


参考:Perlメモ/OHZAKI氏




トラックバック

このエントリーのトラックバックURL:
http://katsubemakito.net/mt/mt-tb.cgi/320

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)

VPSレンタルサーバー




クリエイティブ・コモンズ・ライセンス
このブログは、次のライセンスで保護されています。 クリエイティブ・コモンズ・ライセンス.