質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.57%

連想配列のUASORT関数に関する質問

受付中

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 419

何かのイベントの開始日、終了日、内容メモをカテゴリごとに分けて保持した連想配列を、カテゴリ区分はそのままに、開始日が早い順にソートしたい場合、
以下のように、UASORT関数を使うのが最も簡単で見やすいと考えていますが、下記のような手法で間違いが無いか念のため確認したく、質問を投稿させて頂きました。

★データサンプル
カテゴリで分けられた配列データ群があり、その中には更に複数の配列が格納されています。最小単位のセットには、イベント開始日・イベント終了日・メモが入っています。

$source['category_01']['date_01'] = array('start_date'=>'2018-10-10','end_date'=>'2018-10-15','value'=>'XXXX');
$source['category_01']['date_02'] = array('start_date'=>'2018-10-10','end_date'=>'2018-10-15','value'=>'XXXX');
$source['category_01']['date_03'] = array('start_date'=>'2018-10-10','end_date'=>'2018-10-15','value'=>'XXXX');
$source['category_02']['date_04'] = array('start_date'=>'2018-10-10','end_date'=>'2018-10-15','value'=>'XXXX');
$source['category_02']['date_05'] = array('start_date'=>'2018-10-10','end_date'=>'2018-10-15','value'=>'XXXX');
$source['category_02']['date_06'] = array('start_date'=>'2018-10-10','end_date'=>'2018-10-15','value'=>'XXXX');
$source['category_07']['date_07'] = array('start_date'=>'2018-10-10','end_date'=>'2018-10-15','value'=>'XXXX');
$source['category_07']['date_08'] = array('start_date'=>'2018-10-10','end_date'=>'2018-10-15','value'=>'XXXX');
$source['category_08']['date_09'] = array('start_date'=>'2018-10-10','end_date'=>'2018-10-15','value'=>'XXXX');

★開始日でソートする方法

カテゴリ区分はそのままにしたいので、「同じカテゴリの配列データ群」を一つの配列として、これに対してUASORT関数を使いました。
日付が「日時」に変わっても対応できるよう、ここでは、STRTOTIMEで比較してあります。
開始日が早い順にしたいので、比較対象AのタイムスタンプがBよりも小さい時には-1を返すようにしました。

foreach ($source as $key => $value_array){

    uasort( $source[$key], function( $a, $b ){

        if(strtotime($a['start_date']) === strtotime($b['start_date'])){
          return 0;
        }else if(strtotime($a['start_date']) < strtotime($b['start_date'])){
          return -1;
        }else{
          return 1;
        }

    }
    );
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+2

例示がひどすぎますね

  • 同じ配列内でstart_dateがかぶってたりとか
  • start_dateの値がみんな同じとか

検証がブレるのでよくよく考えて頂いたほうがよいでしょう

$source=[
  'category_01'=>[
    'date_01'=>['start_date'=>'2018-10-19','end_date'=>'2018-10-15','value'=>'XXXX0'],
    'date_02'=>['start_date'=>'2018-10-10','end_date'=>'2018-10-15','value'=>'XXXX1'],
    'date_03'=>['start_date'=>'2018-10-02','end_date'=>'2018-10-15','value'=>'XXXX2'],
    ],
  'category_02'=>[
    'date_04'=>['start_date'=>'2018-10-09','end_date'=>'2018-10-15','value'=>'XXXX3'],
    'date_05'=>['start_date'=>'2018-10-01','end_date'=>'2018-10-15','value'=>'XXXX4'],
    'date_06'=>['start_date'=>'2018-10-15','end_date'=>'2018-10-15','value'=>'XXXX5'],
    ],
  'category_07'=>[
    'date_07'=>['start_date'=>'2018-10-10','end_date'=>'2018-10-15','value'=>'XXXX6'],
    'date_08'=>['start_date'=>'2018-10-11','end_date'=>'2018-10-15','value'=>'XXXX7'],
    ],
  'category_08'=>[
    'date_09'=>['start_date'=>'2018-10-18','end_date'=>'2018-10-15','value'=>'XXXX8'],
    ],
  ];

foreach(array_keys($source) as $key=>$val){
  uasort($source[$val],function($a,$b){
    if(strtotime($a['start_date']) === strtotime($b['start_date'])){
      return 0;
    }else if(strtotime($a['start_date']) < strtotime($b['start_date'])){
      return -1;
    }else{
    return 1;
    }
  });
};
print_r($source);

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/10 12:15

    ご指摘、ご教授ありがとうございます!
    サンプルにミス多くてすみません汗

    例だと、ソースの配列のVALUEは使わないので、書いて頂いたように、array_keys を使うのがよいですね!
    大変勉強になりました。
    ありがとうございます。

    キャンセル

+1

それで動作はすると思いますが、比較関数の部分はPHP7以降導入された宇宙船演算子(「比較演算子」参照)を使うと簡潔に書けますし、間違いが入り込みにくくなります。ほぼこの用途のために用意されてるようなものなので活用しましょう。

    function( $a, $b ){
        return strtotime($a['start_date']) <=> strtotime($b['start_date']);
    }

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/10 12:17

    こんな比較演算子があるんですね・・・
    勉強不足でした。

    めちゃくちゃ便利ですねこれ!!
    ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.57%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る