• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:phpでのソートについて)

phpでのソートについて

このQ&Aのポイント
  • phpのソート処理で日付の新しい順に並び替える方法を知りたいです。同じ日付の場合にも正しい順番で並び替えたいです。
  • ソート処理で同じ日付の場合にランダムな順番ではなく、元のリストの上から順番に並び替えたいです。
  • 具体的なソースコードを教えていただけると助かります。

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

  • ベストアンサー
noname#244856
noname#244856
回答No.4

もしCSV形式としてそのファイルが有効であれば、fgetcsv関数とfputcsv関数が向いていると思います。 PHP Manual - fgetcsv http://php.net/manual/ja/function.fgetcsv.php PHP Manual - fputcsv http://php.net/manual/ja/function.fputcsv.php Pentan.info - fgetcsv関数を文字化け対応 setlocaleの文字コード指定 http://pentan.info/php/fgetcsv_char.html ただ、一度全部の行を1行ずつ配列に読み込ませてはまた1行ずつ保存していくってすごく無駄ですよね。2万件あるなら結構きついと思います。そういうときはシリアル関数の出番です。PHPでは配列をそのままの形で保存したり復元したり出来ます。これであれば10万件程度までは何とかなるでしょう。 PHP Manual - unserialize http://php.net/manual/ja/function.unserialize.php PHP Manual - serialize http://php.net/manual/ja/function.serialize.php それ以上の世界となると、MySQLなどのデータベースを利用する選択肢に限られてきます。以下の回答を参考にどうぞ。 http://okwave.jp/qa/q8501002.html こちらの方法ならば、kmeeさんのおっしゃる通り行番号をあらかじめ用意しておき、 SELECT * FROM table_name ORDER BY date_value DESC, index_value ASC みたいな感じのSQLになると思います。

boroko
質問者

お礼

お忙しい中、ご回答ありがとうございます。 こちらをヒントにして、一度、安定ソートしたデータを 別に保存しておいて、新たに追加されたデータのみを対象にして 安定ソートをかけた後に保存しておいたデータと合算させることにより 無理なく処理が可能になりました。 ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (3)

noname#244856
noname#244856
回答No.3

一応補足しておきますね… ソートの説明についてはkmeeさんの回答が非常に参考になると思います。私の回答では「行番号」に配列のキーをそのまま使用するようにして実現しました。usort関数は値でソート、uksort関数はキーでソートするために使われますが、uksort関数とコールバック関数でのuse句を組み合わせれば、キーと値の両方の情報を同時に使うことが出来ます。 uksort関数の場合、そのままではキーの添え字が維持されるので、振りなおしたい場合はarray_values関数を最後に通す必要があります。

全文を見る
すると、全ての回答が全文表示されます。
noname#244856
noname#244856
回答No.2

<?php $data = array(   array('aaa-12', 'dmy', '2014年3月5日'),   array('ccc-22', 'dmy', '2014年3月5日'),   array('ddd-43', 'dmy', '2014年3月4日'),   array('yyy-45', 'dmy', '2014年3月5日'),   array('ddd-43', 'dmy', '2014年3月2日'), ); uksort(   $data,   function ($a, $b) use ($data) {     return       $data[$a][2] == $data[$b][2] ?       ($a < $b ? -1 : 1) :       ($data[$a][2] < $data[$b][2] ? 1 : -1)     ;   } ); $data = array_values($data); // 添え字を振りなおす場合は必要 foreach ($data as $key => $value) {   $value = implode(', ', $value);   echo "[{$key}] {$value}\n"; } ideone.comでの動作確認 http://ideone.com/cBLHu3

boroko
質問者

補足

お忙しい中ご回答いただきましてありがとうございます。 完全なご回答をいただきながら以下部分でつまづいてしまっております。 $data = array(   array('aaa-12', 'dmy', '2014年3月5日'),   array('ccc-22', 'dmy', '2014年3月5日'),   array('ddd-43', 'dmy', '2014年3月4日'),   array('yyy-45', 'dmy', '2014年3月5日'),   array('ddd-43', 'dmy', '2014年3月2日'), ); こちらをaaa.txtに置き換えして実行したいのですが、 $datax = @file('aaa.txt'); $data = array($datax); これでは駄目なのでしょうか。 色々やってはみたいのですが上手くいかず、 知識がなさすぎて申し訳ありません。 自分なりに調べてからどうしてもわからない場合にお願いをさせていただくのですが、 arrayでの例題が多く、txtファイルなどを使った場合、 どのようにこれを置き換えすれば良いのかが全然理解できておりません。 また、aaa.txtは2万行ぐらいありまして、今後も増えていくのですが あまり増えますとご教授いただいた形ですと厳しいでしょうか。 知識がなさすぎてご迷惑をおかけして申し訳ありません。 もし宜しければご指導いただけますと幸いです。

全文を見る
すると、全ての回答が全文表示されます。
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

ソートには、 同じ「順位」だったときに、元の順番が保存される「安定ソート」 と どうなるかわからない「不安定ソート」 があります。 http://php.net/manual/ja/function.usort.php > 比較結果が等しくなるメンバーが複数存在する場合、 ソート後の配列でのそれらのメンバーの並び順は未定義となります。 と、usortのマニュアルに明記してあります。 つまり、不安定ソートです。(少なくとも、安定ソートとは決めつけることはできない) # http://www.php.net/manual/ja/array.sorting.php # によると、usortだけではなく、他のソートも不安定ソートです。 対策は (1) 用意されたsortではなく、自前で安定ソートのプログラムを用意する (2) 不安定にならないように工夫する のどちらかです。 (1)は他言語のものは見つかりますが、PHPで書かれたものは少ないように思います。 (2)は、不安定になるのは同順位のときなのですから、絶対同一順位にならないようにします 例えば 1,aaa-12,dmy,2014年3月5日, 2,ccc-22,dmy,2014年3月5日, 3,yyy-45,dmy,2014年3月5日, 4,ddd-43dmy,,2014年3月4日, 5.ddd-43,dmy,2014年3月2日, 等と「行番号」を付けて、cmpを「日付が同じなら行番で比較」というように変更します。

参考URL:
http://ja.wikipedia.org/wiki/%E3%82%BD%E3%83%BC%E3%83%88
boroko
質問者

お礼

考え方をご教授いただきましてありがとうございます。 自前で作成できるだけのスキルが全然ありませんので 既存のもので少しずつ理解をしていくしかないようです。 番号を最初につけておいて・・と言う所も大変参考になりました。 お忙しい中、ご面倒にも関わらずありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • Sheet2にある情報をSheet1のA1に1列で

    マクロを作りたいのですが、以下のようなものをどうすればできるかで詰まっています。 Sheet2にある情報をSheet1のA1に1列(A列B列C列の順)で並ぶようにしたいです。 Sheet2の内容は変わることがあるので、データがどの行まで入っているかはマクロを走らせるときにチェックしないとわからないかと思います。 [Sheet1] 111 222 333 aa bb aaa bbb ccc ddd eee -------------------------- [Sheet2] A B C 1 111 aa aaa 2 222 bb bbb 3 333 ccc 4 ddd 5 eee 素人な質問かもしれないですが、調べてもわからなかったので、教えていただけると幸いです。

  • 日付のないところは空欄にしたい。

    EXCELで日付とデーターが並んでいるのですが、 日付が所々間が抜けている日がある場合があります。 抜けている日のところは空欄にして、日付順に並べることは できますか? 例) 10/1  aaa 10/2 bbb 10/4 ccc 10/5 ddd を 10/1  aaa 10/2 bbb 10/4 ccc 10/5 ddd (10/3のところは間をあけたい)

  • SQL文 テーブル1つに複数のデータ

    お世話になっております。 SQLでの質問です。 --テーブル---------- F_1 F_2 AAA BBB AAA CCC BBB XXX CCC DDD DDD YYY 1.F_1のAAAを条件にF_2のBBB・CCCを取得し、 F_1のBBB・CCCと、F_2のXXXとDDDを取得します。 2.次に、取得したF_2のXXX・DDDを条件に、F_1のDDD、F_2のYYYを取得します。 これを1つのSQLで実行したいのですが、副問合せを駆使しても、良いSQLが思い浮かびません。 有識者の方、ご享受頂きたいです。 宜しくお願い致します。

  • xmlからphpでうまくデータを出力できない

    WEBサービスでリクエストに対して取得したxmlの中で、下記のようなデータがあるのですが、それがうまくphpで出力できなくて困っています。 [xmlのデータ(一部)] <aaa>  <bbb>   <ccc>    <ddd>あいうえお</ddd>    <Date date="05" month="09" year="2009"> [phpのソース] echo $aaa->bbb->ccc->ddd ; echo $aaa->bbb->ccc->year ; ・・・(※) (※)の行は思いつきで書いてしまっているのですが、この状態で実行すると、「あいうえお」は取得できますが、日付が当然取得できません。質問は以下です。 (※)の部分は、どう書けばいいのでしょうか?

    • 締切済み
    • PHP
  • diffコマンド結果詳細内容について

    diffコマンド結果詳細内容について 以下、実行ログになります。 test_svrver33%cat aa 123 456 789 aaa bbb ccc ddd test_svrver34%cat bb 123 456 ccc ddd test_svrver35%diff aa bb 3,5d2 < 789 < aaa < bbb test_svrver36% diffコマンドの実行結果1行目の 3,5d2 について 詳しく知りたいのですが 3,5 については3行目~5行目だと わかったのですが、d2 についてどうしても調べきれなかったので ご教授よろしくお願い致します。

  • 【少し急いでます】エクセルについて教えてください!

    Excel2000を使っています。 A列に重複するデータがあり、B列に別データがあります(20000行強) 例)     A  B 1  001 aaa 2   001 bbb 3   001 ccc 4   002 aa 5  002 bb 6  003 aaa 7  003 bbb 8  004 ddd 9   004 eee 10  005 aa 11  006 bbb A列で重複する001は3行あり、重複しているデータは1行にまとめてB列のaaa、bbb、cccをつなげたいです。(わかりづらくてすみません) 例)     A      B 1  001  aaa・bbb・ccc 2  002   aa・bb 3  003  aaa・bbb というようにまとめたいです。 どのような方法がありますでしょうか? よろしくお願い致します。

  • AccessSQL 1つのテーブルに複数のデータ

    お世話になっております。 アクセスSQLでの質問です。 --テーブル---------- F_1 F_2 AAA BBB AAA CCC BBB XXX CCC DDD DDD YYY 1.F_1のAAAを条件にF_2のBBB・CCCを取得し、 F_1のBBB・CCCと、F_2のXXXとDDDを取得します。 次に、取得したF_2のXXX・DDDを条件に、F_1のDDD、F_2のYYYを取得します。 つまり、AAAを取得した結果、SQL一つで、上記テーブルデータをF_1:AAA以外、取得したい要件です。 有識者の方、ご享受頂きたいです。 宜しくお願い致します 【自力で考えた結果】 -------------------------- select F_MenuCD,F_ZaiCD from [TABLE] where F_MenuCD IN ( SELECT F_ZaiCD FROM [TABLE] WHERE F_MenuCD IN ('AAA') ); F_1 F_2 BBB XXX CCC DDD を取得するSQLは上記でいけそうなのですが、 DDD YYY を、1つのSQLで取得したいのです。

  • awkで検索し、特定のフィールドを抽出する方法

    UNIX初心者です。 以下のようなデータファイル(AA.dat)から、条件を満たすデータの特定フィールドを別のファイル(BB.dat)に出力したいのです。 どのようにしたら良いのでしょうか? AA.dat(CSV形式) aaa,22,33,44,55,66,77,88,1,1,0,0,1001 bbb,22,33,44,55,66,77,88,1,1,0,0,1002 ccc,22,33,44,55,66,77,88,1,0,0,0,1001 ddd,22,33,44,55,66,77,88,1,1,0,0,1002 抽出条件(フィールド=$1~$13) $9==1 かつ $10==1 かつ $11==0 かつ $12==0 かつ $13==1002 出力するフィールド $1,$2,$4,$7,$8 出力結果 BB.dat(CSV形式) bbb,22,44,77,88 ddd,22,44,77,88

  • SELECT(結合)について

    次のような操作がしたいのですが、 TestOya t1 t2 1 A 2 B TestKo1 k11 k12 k13 1 1 AA 1 2 BB 2 1 CC TestKo2 k21 k22 k23 1 3 AAA 1 4 BBB 1 5 CCC 2 2 DDD 取得したい結果 t1 t2 betumei1 betumei2 betumei3 1 A 1 1 AA 1 A 1 2 BB 1 A 1 3 AAA 1 A 1 4 BBB 1 A 1 5 CCC 2 B 2 1 CC 2 B 2 2 DDD betumei1には、k11またはk21 betumei2には、k12またはk22 betumei3には、k13またはk23 となるような結合がしたいのです。 アドバイスあれば宜しくお願いします。

  • Excel:既入力項目をドロップダウンリストに(入力規則?)

    Excelで、 ある列に簡単な文字列を入力していっているのですが、 それまでに同じ列で入力したのと同じ内容を入力する際に、 ドロップダウンリストを使いたいと思っております。 入力リストとも思うのですが、内容が固定でなく、 新たな内容を入力したら、それもリストで 使えるようにしたいです。 (例) AAA (空白) (空白) BBB (空白) CCC (空白)     ←ここを入力するときに、      AAA・BBB・CCCから選択またはDDDを手入力     ←上でDDDを入力していたらAAA・BBB・CCC・DDDから選択      そうでなければAAA・BBB・CCCから選択 以下ずっとこんな感じ(新項目を入力したら以後それもリストに入ってほしい) このような場合、どのように設定したらよいのか、 お分かりの方がいらっしゃいましたらご回答ください。