- 締切済み
perlのsortについて
下のテキストをグループ別でabc順にソートしたいのですが AG tanaka abe kaneda BG hayama oota endou CG kawai gennda hirata そのままsort関数を使用し、ソートをするとAG,BG,CGもソートされてしまい、さらに名前もAG,BG,CG関係なしにソートされてしまいます、 AG,BG、CGを動かさず、中身だけをソートする方法はないでしょうか?
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- e_watt
- ベストアンサー率71% (25/35)
個々の作業を安直にコードにして、 グループ名が来るたびに結果を吐き出す方法を採ってみました。 use strict; my @names = (); my $groupName = ''; while (<DATA>) { if (/^[A-Z]+$/) { # グループが始まるなら flush($_); # これまでの分を集計し、グループ名を更新 }else{ push @names, $_; # 名前は配列に追加 } } flush(''); # 入力の終了時にも集計 sub flush { if ($#names >= 0) { # 集計中の名前があれば print $groupName; map { print; } sort @names; # ソートして表示 @names = (); } $groupName = shift; # 新しいグループの名前 } __DATA__ AG tanaka abe kaneda BG hayama oota endou CG kawai gennda hirata
- kumoz
- ベストアンサー率64% (120/185)
テキストを配列に入れれば、グループごとのスライスソートができると思います。なお、グループ名は大文字で、グループ内のテキストは大文字がないものとしています。 use strict; my @list = <DATA>; foreach my $end (0 .. $#list) { if ($end == $#list or $list[$end+1] =~ /[A-Z]/) { my ($start) = grep { $list[$_] =~ /[A-Z]/ } reverse 0 .. $end; @list[$start+1 .. $end] = sort @list[$start+1 .. $end]; } } print @list; __DATA__ AG tanaka abe kaneda BG hayama oota endou CG kawai gennda hirata
- kmee
- ベストアンサー率55% (1857/3366)
方法1: AGに属すものだけのリスト抽出→ソート BGに属すものだけのリスト抽出→ソート→上のAGだけのソート済みのリストに追加 CGに属すものだけのリスト抽出→ソート→上のAGとBGをソート済みのリストに追加 と分割してやる。 方法2: ['AG','tanaka'] ['AG','abe'] 等とグループ+名前の状態でリストにする →グループを優先するようなソートを行う →グループと名前を分割する