データの日付でソートをしたい

このQ&Aのポイント
  • データの日付でソートをしたいと思っていますが、うまくいっていません。
  • $kuchikm2のデータを日付でソートしたいですが、以前ソートで数字でないといけないと言われたため、うまくいっていません。
  • データの日付でソートするためのロジックを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
  • 回答数2
  • ありがとう数7

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

  • ベストアンサー
  • kumoz
  • ベストアンサー率64% (120/185)
回答No.2

> my @lines = $kuchikm2; 上の文では行単位で配列に入らず、要素1の配列になります。まずは、この部分を直すのが先決かと思います。 use warnings; my @lines = map { "$_\n" } split /\n/, $kuchikm2; print @lines, " a\n"; my @sorted = map { $_->[1] } sort { $b->[0] cmp $a->[0]} map { [(split /,/, $_)[4], $_] } @lines; print @sorted, " b\n";

hihin2003
質問者

お礼

回答ありがとうございます。 無事ソートが出来ました!! いつも助かってます。

その他の回答 (1)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

日付がこのフォーマットなら, 単純に文字列として (cmp で) 比較すれば十分ではないかな. あと, Schwartz変換が間違ってる. さらにいうと, 「Schwartz変換は必ずしも効率的ではない」という指摘もあったりします.この場合だと my @dates = map { (split /,/)[4] } @lines; my @sorted = @lines[sort { $dates[$a] cmp $dates[$b] } 0 .. $#lines]; とする手もあります.

hihin2003
質問者

補足

回答ありがとうございます。 cmpて゜比較ですね。早速やってみました。 データ 1,8,,説明文,2010/07/06-01:27, 2,8,,紹介文,2010/07/18-02:27, 3,8,,コメント,2010/05/19-03:27, 4,8,,文言,2010/06/20-04:27, perl実行結果 1,8,,説明文,2010/07/06-01:27, 2,8,,紹介文,2010/07/18-02:27, 3,8,,コメント,2010/05/19-03:27, 4,8,,文言,2010/06/20-04:27, 結果の表示が今回初めて表示されましたが、ソートされていませんでした。 (perlソース) 略 #sortロジック use warnings; my @lines = $kuchikm2; print @lines, " a\n"; my @dates = map { (split /,/)[4] } @lines; my @sorted = @lines[sort { $dates[$a] cmp $dates[$b] } 0 .. $#lines]; print @sorted, " b\n"; (ここまで) あと少しだと思うのですが、どこがどう問題なのかがわかっていません。

関連するQ&A

  • 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
  • perlでCSVをソートする方法について

    perl初心者です。いつもありがとうございます。 perlでcsvファイル(1行のカラム数は200)、総行数は約3万行のファイルを37番目のカラム(-25以上25未満の数値データ)で降順ソートしその値によって行数がだいたい均等になるよう3分割し、2番目のカラムに文字でも数字でもよいのですがその4つのグループごとにフラグ(例えば1,2,3)を入れたいと思ってます。グループ化については境目の37番カラムの値は重複している場合が多いと思うのですがその場合は下(別に上でもかまいません)に入れるものとします。 ソートロジックは過去の質問を参照して理解しましたがグループ化しフラグを入れるルーチンがうまく作れません。下記のように作ったのですがこの先同じことを何度もやらなくてはならないので先に進めません。どなたかお助けください。最終的にやりたいことはカラム37でグループ化→カラム2にフラグを立てる、次にカラム2とカラム38(-25から0までの数値)でソートし同様に同じ行数になるようにグループ化→カラム3にフラグを立てる、さらにカラム2とカラム3とカラム39(-25以上25未満の数値データ)でソートし・・・同様に繰り返し最終的に1グループが100件(行)~150件(行)になるようにしたいのです。つまり約3万件のデータを3*4*2*4*2=192分割(5列の値で分類)したい、そしてどのような範囲で分割したかという情報も得たいのです。 use strict; use warnings; use utf8; use Encode; binmode STDOUT, ':encoding(utf-8)'; my $dir = './data'; # 処理するディレクトリ my $motoFile = 'customer.txt'; # もとファイル open my $fh, '<:encoding(cp932)', "$dir/$motoFile" or die 'ファイルが開けません。',"$!"; my %sorted; while (my $line = <$fh>) { my $key = (split /,/, $line)[37]; push @{$sorted{$key}}, $line; if (@{$sorted{$key}} == 1000) { open OUT, '>>:encoding(cp932)', "$dir/$key.tmp" or die "Can't open: $!"; print OUT @{$sorted{$key}}; close OUT; @{$sorted{$key}} = (); } } open OUT, '>:encoding(cp932)', "$dir/out.txt" or die "Can't open: $!"; foreach my $key (sort { $b <=> $a } keys %sorted) { if (-e "$key.tmp") { open IN, '<:encoding(cp932)', "$dir/$key.tmp" or die "Can't open: $!"; print OUT while <IN>; close IN; } print OUT @{$sorted{$key}} if @{$sorted{$key}}; } close OUT; #↓↓↓↓ここからフラグを作成するルーチン # 行数を調べ3つに分けるルーチン my @colum37; open IN, '<:encoding(cp932)', "$dir/out.txt" or die 'ファイルが開けません。',"$!"; my @in = <IN>; close IN; my $gyousuu = scalar(@in); my $amari = $gyousuu % 3; if ($amari == 0) { my $groupGyousuu = ($gyousuu-$amari)/3; print "総行数は$gyousuu","で、1グループの行数は$groupGyousuu","ほど、余りは$amari\n"; # あまりが0の時、group1は@inの0行 ~$groupGyousuu-1行まで #         group2は@inの$groupGyousuu行 ~$groupGyousuu*2-1行まで #         group3は@inの$groupGyousuu*2行~$groupGyousuu*3-1行まで foreach my $num (1..2) { push @colum37, (split /,/, $in[$groupGyousuu*$num])[37]; # これは境目の先頭の37番目 } print "@colum37\n"; #これでここまでは完成、分けるべき値がこの配列に入っている。 open OUT, '>:encoding(cp932)', "$dir/out.txt" or die "Can't open: $!"; foreach my $line (@in) { my @line = split /,/,$line; if ($line[37]>=$colum37[0]) { $line[1] = 1; }elsif ($line[37]>=$colum37[1] and $line[37]<$colum37[0]) { $line[1] = 2; }elsif ($line[37]<$colum37[1]) { $line[1] = 3; } $line = join (',',@line); print OUT $line; } close OUT; } elsif ($amari == 1) { この後未作成

    • ベストアンサー
    • Perl
  • 特定のデータだけををソートしたい

    POSTで渡されたデータの中から特定のデータだけを取り出しソートしたい。 例えばNo・名前・年齢のtextを数個表示してNoだけを抽出し、ソートして昇順にしたいのですが? print '<form name="form1" action="eee.php" method="POST">' . "\r\n"; for($i=0;$i<5;$i++){ print '<input type="text" name="N0'.$i.'">' . "\r\n"; print '<input type="text" name="Name'.$i.'">' . "\r\n"; print '<input type="text" name="Age'.$i.'">' . "\r\n"; } print '<input type="submit" value="送信">' . "\r\n"; print '</form>' . "\r\n";

    • 締切済み
    • PHP
  • 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
  • CSVデータ「","」と「,」混在読取り出来ず

    ソート機能がうまく動作しなくなりました。 CSVが以下のようなものとなったときにソートがうまく動作しなくなってしまいました。 CSVデータの区切りが「","」と「,」の混在で区切られてます。 (ここから) データa "山田","埼玉県","男性" "田中","埼玉県","男性" "井上","栃木県","女性" "志村","千葉県","男性" (ここまで) だったり (ここから) データb 1,山田,埼玉県,男性,50,"予算2,000円",0 2,田中,埼玉県,男性,36,予算なし,0 3,井上,栃木県,女性,30,予算100円,0 4,志村,千葉県,男性,27,"予算300,000円",0 (ここまで) このようなテータの時もあります。 以前のアドバイスをもとに以下のように作成いたしました。 (ここから) while (my $line = <$ifh>) { if ($socnt == 0 ){$socnt++;next;} my $key = (split /\",\"/, $line)[$ccsv]; push @{$sorted{$key}}, $line; if (@{$sorted{$key}} == 1000) { open OUT, ">>./$key.tmp" or die "Can't open: $!"; print OUT @{$sorted{$key}}; close OUT; @{$sorted{$key}} = (); } } (ここまで) この場合だと my $key = (split /\",\"/, $line)[$ccsv]; データaはうまくいくのですが、データbがうまくソートが動作いたしません。 my $key = (split /,/, $line)[$ccsv]; ではデータbはうまくいくのですが、データaうまくソートが動作いたしません。 条件式で混在認識方法があるかと思っている(ないかもしれませんが、わたしには分かりません)ので質問いたしました。 ご教授いただけますと幸いです。 よろしくお願いします。

    • ベストアンサー
    • Perl
  • Lingua::JA::Sort::JISのソート

    お世話になっております。 Lingua::JA::Sort::JISモジュールを使用して、 五十音ソートを行ってますが、 うまく五十音ソートができません。 具体的には配列Nameの順番がほとんど変わらない状態で 出力されてしまいます。 なぜうまくソートできないのでしょうか? <環境> OS:FreeBSD 7.1-RELEASE-p15 i386 Apache:Apache/1.3.42 (Unix) mod_ssl/2.8.31 OpenSSL/0.9.8e Perl:5.8.9 モジュールの使い方はこちらを参考にしました。 http://okwave.jp/qa/q3412594.html 上記URLでは、文字コードの変換を行っていますが、 UTF-8でスクリプトを書いているので文字コードの変換は 不要と考えています。 Lingua::JA::Sort::JISモジュールは下記URLから取得し、 LinguaJASortJIS.pmへリネームし、カレントディレクトリへ設置しています。 http://cpansearch.perl.org/src/SADAHIRO/Lingua-JA-Sort-JIS-0.05/JIS.pm 以下スクリプトです。 test.cgi -- #!/usr/local/bin/perl use utf8; use LinguaJASortJIS; binmode(STDIN, ":utf8"); binmode(STDOUT, ":utf8"); print "Content-type: text/html\n"; print "Pragma: no-cache\n"; print "Cache-Control: no-cache\n"; print "Expires: Thu, 01 Dec 1994 16:00:00 GMT\n"; print "\n"; print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n"; print "<html lang=ja>\n\n"; print "<head>\n"; print "<meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\">\n"; print "</head>\n\n"; print "<body>\n"; my @Name = ("みかん", "@なし", "ちくわ", "マルチョウ", "もも", "たまご", "シロ丸", "Pig", "てばさき☆", "ホルモン~", "ギアラ・アカセン", "ミノ", "SENMAI☆", "蜂巣", "焼きセンマイ♪", "バウムクーヘン", "MinoII", "(有)蜂巣JP", "生レバーIII"); my @NameSort; my $Jis = Lingua::JA::Sort::JIS->new; #ソート前 print "ソート前"; print "<table border=1>"; print "<tr><td>name</td><td>utf8 flag</td></tr>"; for (my $i = 0; $i <= $#Name; ++$i) { print "<tr><td>".$Name[$i]."</td><td>".utf8::is_utf8($Name[$i])."</td></tr>"; } print "</table>"; #ソート for my $Sort ($Jis->jsort(@Name)) { push(@NameSort, $Sort); } print "ソート後\n"; print "<table border=1>"; print "<tr><td>name</td><td>utf8 flag</td></tr>"; for (my $i = 0; $i <= $#NameSort; ++$i) { print "<tr><td>".$NameSort[$i]."</td><td>".utf8::is_utf8($NameSort[$i])."</td></tr>"; } print "</table>"; print "</body></html>"; -- 以上、よろしくお願いします。

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

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

    • ベストアンサー
    • 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
  • データファイルのソート方法について

    perlで使用している、データファイルのソート方法について質問いたします。 やりたいこと。 1.ファイルを読み込み 2.指定されている文字列でソートをして 3.同じファイルに格納する 以上になります。 以下のファイルにデーターが入ってます・ namedata.cgi 田中,4 佐藤,2 鈴木,1 水野,3 このファイルをソートして以下のように並び替えて保存したいと思ってます。 スクリプトを実行後 namedata.cgi 鈴木,1 佐藤,2 水野,3 田中,4 となっていてほしいのです。 スクリプト sort.cgi 略・・・ #ふぁいる読み込み open(DB,"<$file") || &error("Can't write $file"); flock(DB, 1); @lines = <DB>; close(DB); #ソート @result = sort { $a <=> $b } @lines; #ファイル書き込み open(DB,">$file") || &error("Can't write $file"); flock(DB, 2); print DB "@result"; close(DB); ファイルの2項目目が分からないからソートされていないような気がするのですが、記述方法がわかりません。 ファイル読み込み時にforeachを使用して読み込まないとだけなのでしょうか? うまく説明できていないかもしれませんが、よろしくお願いいたします。

    • ベストアンサー
    • 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

専門家に質問してみよう