• 締切済み

Perlの文字列ソートについて

こんにちわ。 例えば、 あいう,2002/04/12, ななな,2002/04/14, あいう,2002/04/20, というlogがあったとして、これを表示させるときには、 あいう 2002/04/12 あいう 2002/04/20 ななな 2002/04/14 といった具合に出力させたいのですが、そのsortのさせ方がわかりません。 my @lines = sort by_no(@lines); sub by_no { my $no1 = (split(/,/,$a))[0]; my $no2 = (split(/,/,$b))[0]; $no2 cmp $no1; } ではどこがいけないのでしょうか? 教えてください。お願いします。

  • CGI
  • 回答数1
  • ありがとう数2

みんなの回答

  • leaz024
  • ベストアンサー率75% (398/526)
回答No.1

> ではどこがいけないのでしょうか? ということですが、どのようにダメなのでしょうか? コピーして確認したところ、単に逆順にソートされてしまうだけのようです。 文字列を昇順(あいうえお順)にソートしたい場合、   $no2 cmp $no1; ではなく、   $no1 cmp $no2; とします。 ちょっと気になった部分として、 > my @lines = sort by_no(@lines); のところですが、既存の配列 @lines を、ここで my 宣言するのはどうかな、と思います。 正しく動作するようですが、下記のようにした方がよいと思います。 ・元の配列の内容は不要 → my 宣言しない(@lines を書き換える) ・元の配列の内容も必要 → my 宣言する配列名を変える(@sorted_logs など) また、「同じ文字列の場合は日付順にしたい」という要望も出てくると思うのですが、その際、古い順でよければ比較関数は省略できます。 (0埋めされた固定長の日付文字列は、文字コード昇順が、そのまま古い順になります。)   my @sorted_logs = sort @lines; ※コンマ左の文字列の部分に、コンマより小さい文字コードの文字が入らないことが前提です。全角のみなら問題ありません。

関連するQ&A

  • csv元データーの数字の列が、""で囲まれているせいか、数値としてのソートできません

    次の式でソートしたいのですが、 @LINES = sort { (split(/\,/,$a))[0] <=> (split(/\,/,$b))[0] } @LINES; csv元データーの数字の列が、 "28000000","鈴木", のように""で囲まれているせいか、<=>で数値としてのソートできません。 cmpで文字列としてのソートは出来ます。 どうしたら良いのでしょうか?

    • ベストアンサー
    • Perl
  • perlで大容量CSVのsort方法について

    perlで大容量CSVのsort方法について perlでcsvファイル100MB超のファイルをソートしたいと思ってますが、以下の方法でメモリーの関係上(と思ってます。)できません。 ソートを行う方法がありますでしょうか? 件数も11万件あるので、エクセルでソートしてからの受け渡しが出来ずに悩んでます。 (ここから) #sortロジック sub sort { use warnings; use feature ':5.10'; open my $ifh, '<', $inport or &error("Can't open $inport"); my @lines = <$ifh>; close $ifh; print @lines, "\n"; #csvファイル何番目? my @sorted = map { $_->[0] } sort { $b->[0] <=> $a->[0]} map { [(split q{,}, $_)[0], $_] } @lines; @lines = @sorted; exit; } (ここまで) いつも貴重なアドバイスをありがとうございます。よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • 重複を無くしてのソートの定石は?

    sortで、 $lines[0] = "02"; $lines[1] = "02"; $lines[2] = "01"; $lines[3] = "03"; で、 01 02 03 と重複を無くしてソートしたいときに、 sort { $a cmp $b } @lines の{}部分を変更してこれを実現する「定石」なる方法はあるでしょうか?sortを使わない定石方法でもいいです。

    • ベストアンサー
    • Perl
  • データの日付でソートをしたい

    データの日付でソートをしたい データの日付でソートをしたいと思ってますが、うまくいっていません。 $kuchikm2の内容 1,8,,説明文,2010/07/06-01:27,1,,,,,,, 2,8,,紹介文,2010/07/18-02:27,1,,,,,,, 3,8,,コメント,2010/05/19-03:27,1,,,,,,, 4,8,,文言,2010/06/20-04:27,1,,,,,,, ソートした結果@sorted 2,8,,紹介文,2010/07/18-02:27,1,,,,,,, 1,8,,説明文,2010/07/06-01:27,1,,,,,,, 4,8,,文言,2010/06/20-04:27,1,,,,,,, 3,8,,コメント,2010/05/19-03:27,1,,,,,,, (perlソース) 略 #sortロジック use warnings; my @lines = $kuchikm2; print @lines, " a\n"; my @sorted = map { $_->[4] } sort { $a->[0] <=> $b->[0]} map { [(split q{,}, $_)[4], $_] } @lines; print @sorted, " b\n"; (ここまで) 以前ソートで質問したときに、数字でないといけないと言われたような気がしています。 お手数かけます。 よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • grepとsort

    my $files = readdir(DIR); @files = grep { !/^\.\.?$/; } @files; 「.」と「..」の除去 @files = sort { $a cmp $b; } @files; ファイル名のソート この2文についてですが、grepとsortに関する文法がよくわかりません。 grepって、除去するコマンドなんでしょうか? sortでは、$a cmp $bが何を意味しているのでしょうか。

    • ベストアンサー
    • Perl
  • ソートの方法

    某CGIを改造中です。 記事を更新日順でソートしなおしたいです。 多分、ソート部分だと思われる部分の現状は、 ----- foreach (@data) {   ($no,$year1,$month1,$day1,$name~~) = split(/<>/);   @tmp = ();   @tmp = map {(split /<>/)[0]} @data;   @data = @data[sort {$tmp[$b] cmp $tmp[$a]} 0 .. $#tmp]; } ----- です。 ただ、見ての通り、日付が「$year1,$month1,$day1」と分かれています。これを結合して(20060309のような形)、それを元にソートしなおしたいのですが、どのようにしたら良いでしょうか? 方法を教えてください。お願いします。

    • ベストアンサー
    • Perl
  • 区切りファイルの列ソートについて

    僭越ながら、質問させていただきます。 タブ記号で区切られたTSVファイルというものを扱っているのですが、まずtest.tsvファイルを配列に格納して、そこから2列目の値すべてを降順にソートし、 (列をソートした結果の行は、ちゃんと最初のまま保持され、バラけずに出力されるようにしたい) その結果をresult.txtに表示させるプログラムを作りたいと思っております。 ですが、自分が書いたプログラムではまったく動かず、どこが悪いのかも情けないことにわかりません…。  かれこれ何時間も悩んでいますが、まったく方策が見出せません。どこをどう直せばいいのか、ヒントだけでも構いませんので、教えてくださいませんでしょうか。 プログラムは以下です。 #!/usr/bin/perl use strict; use warnings; use Fatal qw/ open /; my @values; my $tsv_file = "test.tsv"; my @tsv = &readtsvfile($tsv_file); @values = sort { $a->[1] cmp $b->[1] } @tsv; open(DATAFILE, '>>result.txt') or die("error :$!"); foreach(@tsv){ print DATAFILE; } sub readtsvfile { open(IN, $_[0]); while(<IN>) { chomp; push @tsv, [ split(/\t/) ]; } close(IN); return @tsv; } close DATAFILE; このプログラムの手直しでも新しい方法でもなんでも構いません、何か教えてくだされば、本当にありがたいです。よろしくお願いします。

    • ベストアンサー
    • Perl
  • perlで比較関数を使ったソートの仕方

    今、季節をソートするようなプログラムを考えています。 my @array = ('spring','fall','winter','summer'); my @sort = sort number(@array); sub number { if ($a < $b) { return -1; } elsif ($a == $b) { return 0; } elsif ($a > $b) { return 1; } } 実行結果:spring ,summer ,fall ,winter 比較関数を使用して、「春・夏・秋・冬」とソートできるようにしたいです。上のプログラムはまだ途中なんですが、この場合比較関数はどのように実装すればうまくソートできるんでしょうか?分かる方、よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • 配列の連想配列のソート

    お世話になります。mooTaihenです。 Perlで配列のソートが出来なくて困っております。 お忙しいところ、誠に申し訳けありませんが、ご教示をお願い致します。 【内容】  サンプルソースに示した様なデータ構成をソートしたいのですが、思惑通りに行きません。  期待しているソート結果は、 a1 b3 b4 c2  です。  <サンプルソース> my @data; $data[0]{name} = "b"; $data[0]{cnt} = 4; $data[1]{name} = "c"; $data[1]{cnt} = 2; $data[2]{name} = "b"; $data[2]{cnt} = 3; $data[3]{name} = "a"; $data[3]{cnt} = 1; @data2 = sort {chg($a,$b)} @data; foreach (@data2) { print $_->{name} . $_->{cnt} . "\n"; } sub chg { my(@s,@d)=@_; return $s[0]{name} cmp $d[0]{name} and $s[0]{cnt} <=> $d[0]{cnt}; }  <出力結果> a1 b3 c2 b4

    • ベストアンサー
    • Perl
  • cgiでの並べ替えについて

    フォームを使用して書き込みされたログファイルを並べ替えしているんですが、意図しない動きをするんです。 ログデータは以下のような感じです。 a=***&b=***&c=***&d=***&e=*** #-----並べ替えを行う open (FILE2,"<naisen.log"); flock(FILE2,2); @log2 = <FILE2>; flock(FILES,8); close FILES; @sort2 = sort {(split(/[&=]/,$a))[7] <=> (split(/[&=]/,$b))[7];} @log2; @sort3 = sort{(split(/[&=]/,$a))[5] cmp (split(/[&=]/,$b))[5];}@sort2; open (FILE2,">naisen.log"); flock (FILE,2); @filew = @sort3; print FILE2 @filew; close(FILE2); a=***&b=***&c=***&d=120 a=***&b=***&c=***&d=111 というデータがあった場合、意図している動きは a=***&b=***&c=***&d=111 a=***&b=***&c=***&d=120 という順番に並べ替えられるものですが、 a=***&b=***&c=***&d=120 a=***&b=***&c=***&d=111 です。 なぜ111の方が下にきてしまっているのでしょうか? また全部ではなく一部だけに並べ替えが適用されないのはナゼでしょうか?

    • ベストアンサー
    • CGI

専門家に質問してみよう