【PHP】プログラミング、知恵を貸してください。


配列 $hiduke[X(0~いくつか)] があり、中には
2007/02/12 や 2002/03/01 1999/12/30 2007/02/14 2007/01/20
などの(年月日が/で区切られた)日付けが順不同で入っています。

↑を例にすると これを
○2007
 01月 は 20日
 02月 は 12日、14日
○2002
 03月 は 01日
○1999
 12月 は 30日

のように、『配列にあるものだけ』を
『年、月ごと』に『新しい順』に出力させたいです。

どなたか宜しくお願いします。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2007/03/08 17:17:29
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:Mook No.4

回答回数1314ベストアンサー獲得回数393

ポイント40pt

例のように表示を実装した例です。

<?
    $hiduke = array( '2007/02/12', '2002/03/01', '1999/12/30', '2007/02/14', '2007/01/20' );

   // 年を降順にするために先頭にデータを付加
    for( $i=0 ; $i<count( $hiduke ) ; $i++ ) {
        $dt = explode( '/', $hiduke[$i] );
        array_unshift( $dt, 10000 - $dt[0] );
        array_splice( $hiduke, $i, 1, implode( '/', $dt ) );
    }
    sort( $hiduke );

   // データを表示
    $yy = 0;
    $mm = 0;
    $dd = 0;
    foreach ( $hiduke as $d ) {
        $dt = explode( '/', $d );
    // 年の表示
        if ( $yy != $dt[1] ) {
            if ( $dd != 0 ) print "<br>\n";
            $yy = $dt[1];
            $mm = 0;
            print "○$yy<br>\n";
        }
    // 月の表示
        if ( $mm != $dt[2] ) {
            if ( $mm != 0 ) print "<br>\n";
            $dd = 0;
            $mm = $dt[2];
            print "&nbsp;&nbsp;{$mm}月 は ";
        }
    // 日の表示
        if ( $dd != 0 ) print "、";
        $dd = $dt[3];
        print "{$dd}日";
    }
    print "<br>\n";
?>

ご参考までに

id:seasons

詳しくありがとうございます。

コピペしただけで動きました><

他の方のも参考にして色々やってみます。

2007/03/08 17:15:55

その他の回答3件)

id:kn1967 No.1

回答回数2915ベストアンサー獲得回数301

ポイント20pt

年は降順で、月と日は昇順という混在だから困っているという事でよろしいでしょうか?

だとすれば「2つの日付を比較して並び替えるかどうかを判断するための自作関数」を作っておいて

usort という関数でソートして、後は foreach で1つ1つ絞り出して適宜処理すればお望みの事が可能になります。


↓ phpのマニュアルのサンプルが参考になります。

http://jp.php.net/manual/ja/function.usort.php

お暇なときにマニュアルを流し読みするだけでもスキルかなりアップしますのでマニュアルにはブックマークをお勧めします。

id:seasons

foreachやifを使い、長い文にするにはできるのですが、

もっとわかりやすくて軽い方法が知りたいです。

2007/03/08 16:40:46
id:nandedarou No.2

回答回数230ベストアンサー獲得回数34

ポイント20pt

1.sort関数で配列を日付順に並べ替える

http://au3.php.net/manual/ja/function.sort.php

2.foreach内で表示する処理を書く


foreach内の処理は、次のようになるでしょう。


(1)要素を、splitで'/'の位置で分解し、年、月、日をそれぞれ$year、$month、$dayに入れる。

次のアドレスに、やり方が書いてあります。

http://au3.php.net/manual/ja/function.split.php

(2)$old_yearと$yearが同じなら、出力しない。

   違うなら、"\n○{$year}\n"を出力し、$old_monthと$old_dayをクリア

(3)$old_monthと$monthgaが同じなら、"、"を出力

   違うなら、" {$month} 月は"を出力し、$old_dayをクリア

(4)$old_dayと$dayが同じなら、出力しない。

   違うなら、"{$day} 日"を出力

(5)$year、$month、$dayをそれぞれ、$old_year、$old_month、$old_dayにコピーする。

これをコーディングすればいいのではないでしょうか?

id:seasons

ありがとうございます。

いろんな回答があったので一通り試してみます。

2007/03/08 16:58:05
id:vector_xenon No.3

回答回数113ベストアンサー獲得回数4

ポイント20pt
$year = $month = $day = array();
foreach ($hiduke as $val) {
    list($year[], $month[], $day[]) = explode("/", $val);
}

array_multisort($year, SORT_DESC, SORT_STRING,
                $month, SORT_ASC, SORT_STRING,
                $day, SORT_ASC, SORT_STRING,
                $hiduke);

例のように出力するだけであれば、最後の$hidukeは要りません。

id:seasons

シンプルですね

参考にしてみましたがなかなかうまく表示されません。

 02月 は 12日、14日 とか・・

2007/03/08 17:14:38
id:Mook No.4

回答回数1314ベストアンサー獲得回数393ここでベストアンサー

ポイント40pt

例のように表示を実装した例です。

<?
    $hiduke = array( '2007/02/12', '2002/03/01', '1999/12/30', '2007/02/14', '2007/01/20' );

   // 年を降順にするために先頭にデータを付加
    for( $i=0 ; $i<count( $hiduke ) ; $i++ ) {
        $dt = explode( '/', $hiduke[$i] );
        array_unshift( $dt, 10000 - $dt[0] );
        array_splice( $hiduke, $i, 1, implode( '/', $dt ) );
    }
    sort( $hiduke );

   // データを表示
    $yy = 0;
    $mm = 0;
    $dd = 0;
    foreach ( $hiduke as $d ) {
        $dt = explode( '/', $d );
    // 年の表示
        if ( $yy != $dt[1] ) {
            if ( $dd != 0 ) print "<br>\n";
            $yy = $dt[1];
            $mm = 0;
            print "○$yy<br>\n";
        }
    // 月の表示
        if ( $mm != $dt[2] ) {
            if ( $mm != 0 ) print "<br>\n";
            $dd = 0;
            $mm = $dt[2];
            print "&nbsp;&nbsp;{$mm}月 は ";
        }
    // 日の表示
        if ( $dd != 0 ) print "、";
        $dd = $dt[3];
        print "{$dd}日";
    }
    print "<br>\n";
?>

ご参考までに

id:seasons

詳しくありがとうございます。

コピペしただけで動きました><

他の方のも参考にして色々やってみます。

2007/03/08 17:15:55
  • id:nandedarou
    年は降順で、月と日は昇順だとは気づかず、すみませんでした。
  • id:seasons
    nandedarouさん、
    細かいところに気づいてくれて、修正
    ありがとうございます

    是非ともまた宜しくお願いします。
  • id:nandedarou
    ほとんどMookさんのロジックと一緒なので、一度掲載してみたものの削除しましたがseasonsさんからコメントをいただけたので、もう一度、掲載します。(先程、掲載したものもミスがあったので多少修正しました。)
    ※ソートの部分はMookさんのアイデアです。

    $hiduke = array('2007/02/12','2002/03/01','1999/12/30','2007/02/14','2007/01/20');

    foreach($hiduke as $key => $value){
    list($year,$month,$day)=split('/',$value);
    $hiduke[$key] = 10000-$year."/".$month."/".$day."/".$year;
    }
    sort( $hiduke );

    foreach($hiduke as $value){
    list($dummy,$month,$day,$year)=split('/',$value);
    if($year<>$old_year){
    if($old_year<>'') print("<br>");
    print("○{$year}");
    $old_month='';
    $old_day='';
    }
    if($month<>$old_month){
    print("<br> {$month}月 は ");
    $old_day='';
    }else{
    print("、");
    }
    if($day<>$old_day){
    print("{$day}日");
    }

    $old_year=$year;
    $old_month=$month;
    $old_day=$day;
    }

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません