• ベストアンサー

ソート処理

ついこの間正規表現のことで質問させていただいたものです なんとか問題は解決しました それとは別にソート関連での質問があります 正規表現の前にソートについて質問してご回答を頂いてからそれを参考に試してみました http://oshiete1.goo.ne.jp/kotaeru.php3?q=1882190 です push で@tmpの内容を ($score,$filename,$title,$sentenceの順番に) 3.5 abc.txt あいうえお aaaaa 4.6 def.txt かきくけこ bbbbb 2.8 ghi.txt さしすせそ ccccc 5.1 jkl.txt たちつてと ddddd という風にしました このリストを @tmp = map {$_->[0]} sort {$a->[0] <=> $b->[0]} map {[$_, split /<>/]}@tmp; としたんですが結果は abc.txt あいうえお aaaaa def.txt かきくけこ bbbbb ghi.txt さしすせそ ccccc jkl.txt たちつてと ddddd 3.5 4.6 2.8 5.1 というふうになってしまいます これを スコア順に 5.1 jkl.txt たちつてと ddddd 4.6 def.txt かきくけこ bbbbb 3.5 abc.txt あいうえお aaaaa 2.8 ghi.txt さしすせそ ccccc としたいのですがうえのソースでは何がいけないんでしょうか??

質問者が選んだベストアンサー

  • ベストアンサー
  • hara_peko
  • ベストアンサー率28% (11/38)
回答No.3

以下のスクリプトが私が試した内容です。比較してみて下さい。 my @tmp; while (<DATA>) { push @tmp, $_; } @tmp = map {$_->[0]} sort {$b->[1] <=> $a->[1]} map {[$_, split /<>/]}@tmp; print @tmp; __END__ 3.5<>abc.txt<>あいうえお<>aaaaa 4.6<>def.txt<>かきくけこ<>bbbbb 2.8<>ghi.txt<>さしすせそ<>ccccc 5.1<>jkl.txt<>たちつてと<>ddddd

その他の回答 (7)

  • kapura
  • ベストアンサー率50% (48/95)
回答No.8

ソート処理のコードには間違いがないのですから、その入力@tmpを疑うべきではないでしょうか。@tmpがどうなっているか単純にprint '@tmp: ', "\n@tmp\n";みたいなのを入れてみてチェックしてみたら解決につながると思います。 # 別の処理をしてからこのソート処理をするのであれば、別の処理はソート処理の入力に相応しい形式で出力させる必要があります # ソート処理後に別の処理で変更されている可能性もあります # No.1の説明で理解できないのであれば、No.6の方のようなコードの方が理解した上で改変できていいのではないでしょうか No.6の方のやり方はハッシュを使っていますが、そのキーとして数値を使うのは問題だと思います (数値は異なるレコードで重複する場合があり得ると思うので)。もしこのように数値を@scoreとして取り出しているのであれば、%all_hなどは必要なく単純に for(sort {$score[$b] <=> $score[$a]} 0..$#score) { print $data[$_]; # @dataと@tmpは同じもの } のようにすればいいのではないでしょうか。つまり、No.3と同様のコードを示すと、 my @tmp; my @score; while (<DATA>) { push @tmp, $_; push @score, (split /<>/)[0]; } for (sort {$score[$b] <=> $score[$a]} 0..$#score) { print $tmp[$_]; } __END__ 3.5<>abc.txt<>あいうえお<>aaaaa 4.6<>def.txt<>かきくけこ<>bbbbb 2.8<>ghi.txt<>さしすせそ<>ccccc 5.1<>jkl.txt<>たちつてと<>ddddd

gonntetu
質問者

お礼

ご回答してくださった方々ありがとうございました 完全に問題が解決したわけではありませんが ソートだけのスクリプトだけを作成し実行したら上手く動作したので あとはこれを応用して問題を解決したいと思います 本当にありがとうございました

回答No.7

既に No.3 で答えは出ています。 あなたの質問に書いた処理と No.3 の処理は違います。(sortの対象が違います)。 よく読んで下さい。

gonntetu
質問者

補足

0と1がちがうんですよね?? sort をインデックス 1 に書き換えました ソート処理だけのスクリプトを作成し実行させるとうまくいきました しかしこれを別のスクリプトと組み合わせて使うと一行目にまとまってしまいます {$b->[1] <=> $a->[1]} とすると一行目にスコアがまとまり {$a->[1] <=> $b->[1]} とすると最後の行にまとまってしまいます

  • SE-1
  • ベストアンサー率57% (26/45)
回答No.6

素人考えですが、こんなんどうでしょう。ご希望の結果にはなると思います。 @data=qw/3.5,abc.txt,あいうえお,aaaaa 4.6,def.txt,かきくけこ,bbbbb 2.8,ghi.txt,さしすせそ,ccccc 5.1,jkl.txt,たちつてと,ddddd/; foreach(@data){ /^([\d|.]+?),/mg; push @score,$1; } $score_n = @score; for ($i=0;$i<$score_n;$i++){ $all_h{$score[$i]}=$data[$i]; } for(sort { $b <=> $a } keys %all_h){ print "$all_h{$_}\n"; } ちなみにリファレンスと無名配列による多次元配列は以下のサイトがわかりやすいかと。

参考URL:
http://takenaka-akio.cool.ne.jp/doc/perl_kiso/reference3.html
  • hara_peko
  • ベストアンサー率28% (11/38)
回答No.5

No.3のスクリプトを動かしてみましたか? その結果と比べてみてどうでしょう?

gonntetu
質問者

補足

実はNo.3のコードと同じ処理をしています foreachでまわしてpushしていますので違いは無いかと思います 起用にスコアの値だけを一行目に集めてさらにスコアだけをソートしちゃってます^^;;; ちなみに自分にはそんな難しい処理をすることは出来ません

  • hara_peko
  • ベストアンサー率28% (11/38)
回答No.4

・・・もしかして @tmp の中身、 my @tmp = ( 3.5, "abc.txt", "あいうえお", "aaaaa\n", 4.6, "def.txt", "かきくけこ", "bbbbb\n", 2.8, "ghi.txt", "さしすせそ", "ccccc\n", 5.1, "jkl.txt", "たちつてと", "ddddd\n", ); みたいになってたりしませんか? #そうだったにしても1行目の 3.5 4.6 2.8 5.1 は謎ですが。

gonntetu
質問者

補足

なっていません <>でくぎってます なぞの一行目の数値はしっかりソートされています この問題は解決できないんでしょうか??

  • hara_peko
  • ベストアンサー率28% (11/38)
回答No.2

No.1です。先ほどのお話は 3.5 abc.txt あいうえお aaaaa は 3.5<>abc.txt<>あいうえお<>aaaaa の打ち間違えで、 $tmp[0] が 3.5<>abc.txt<>あいうえお<>aaaaa であると仮定しています。

gonntetu
質問者

補足

0を1に変えてためしてみたところ 3.5 4.6 2.8 5.1 5.1 4.6 3.5 2.8 abc.txt あいうえお aaaaa def.txt かきくけこ bbbbb ghi.txt さしすせそ ccccc jkl.txt たちつてと ddddd のような感じになってしまいました 結構多くのサイトを見てみたんですけどどこも教えていただいたソースコードでちゃんと出来ているみたいです となると何がいけないんでしょうか??普通にソースコードを書いてアップロードしてるだけなのですが…

  • hara_peko
  • ベストアンサー率28% (11/38)
回答No.1

@tmp = map {$_->[0]} sort {$b->[1] <=> $a->[1]} map {[$_, split /<>/]}@tmp; です。 [$_, split /<>/] で、無名配列に 0 のところに 3.5 abc.txt あいうえお aaaaa 1 のところに 3.5 2 のところに abc.txt 3 のところに あいうえお 4 のところに aaaaa が入ります。 ですから sort はインデックス 1 の部分を使います。 それと昇順降順が逆ですので、 {$b->[1] <=> $a->[1]} となります。

関連するQ&A