PHP日付を含む要素で多次元配列をソートします


113

私は次のような配列を持っています:

Array
(
[0] => Array
    (
        [id] => 2
        [type] => comment
        [text] => hey
        [datetime] => 2010-05-15 11:29:45
    )

[1] => Array
    (
        [id] => 3
        [type] => status
        [text] => oi
        [datetime] => 2010-05-26 15:59:53
    )

[2] => Array
    (
        [id] => 4
        [type] => status
        [text] => yeww
        [datetime] => 2010-05-26 16:04:24
    )

)

誰かがこれを日時要素に基づいてソート/順序付ける方法を提案できますか?

回答:


205

usort()カスタム比較関数の使用:

function date_compare($a, $b)
{
    $t1 = strtotime($a['datetime']);
    $t2 = strtotime($b['datetime']);
    return $t1 - $t2;
}    
usort($array, 'date_compare');

編集:データは配列の配列で編成されます。それらをよりよく区別するために、内部配列(データ)レコードを呼び出して、データが実際にレコードの配列になるようにします。

usortこれらのレコードのうち2つをdate_compare()一度に指定の比較関数に渡します。 date_compare次に"datetime"、各レコードのフィールドをUNIXタイムスタンプ(整数)として抽出し、その差を返します。その結果0、両方の日付が等しい場合、結果は最初の日付($a)が大きい場合は正の数、 2番目の引数($b)が大きくなっています。 usort()この情報を使用して配列をソートします。


1
この例では、$ arrayに要素$ aと$ bを含める必要がありますか?-無効な比較機能でエラーが発生する
Tim

いや、$a及び$b内の配列を保持します$array。関数名のスペルを間違えていないことを確認してください。
フェルディナンドバイヤー

私は上手く理解できていない気がします。私の例では、配列に3つの配列があります-名前を確認しましたが、無効な比較関数を取得しています
Tim

追加した説明を参照してください。コードをテストしたところ、問題なく動作しました。
フェルディナンドバイヤー

9
CodeIgniterはわかりませんが、クラス内で関数を定義していますか?それをクラスの外で定義するか、別のコールバック引数を使用する必要があります:usort($array, array($this, "date_compare"))、それはそれusort()がクラスの関数/メソッドであることを知っています。参照:php.net/manual/en/...
フェルディナント・バイエル

45

これはうまくいくはずです。strtotimeを使用して日付をUNIX時間に変換しました。

  foreach ($originalArray as $key => $part) {
       $sort[$key] = strtotime($part['datetime']);
  }
  array_multisort($sort, SORT_DESC, $originalArray);

ワンライナーバージョンは、複数の配列メソッドを使用します。

array_multisort(array_map('strtotime',array_column($originalArray,'datetime')),
                SORT_DESC, 
                $originalArray);

これはうまくいきます。$ originalArrayを多次元配列の名前に置き換えてください。そして、「datetime」を日付のサブ配列フィールドの名前に置き換えます。ありがとう。
2017年

1
この解決策は私にとってうまくいっています。ソートオプションも素晴らしいです(SORT_ASCまたはSORT_DESC)。どうもありがとう。
Andras Barth、2018年

1つの小さな警告(それでも、何か間違っている)でも問題なく動作します...並べ替えに必要な日付フィールドには、dd / mm / yyyyまたはyyyy / mm / dd(スラッシュ付き)の形式の日付があります。その場合、何らかの理由で並べ替えが機能しませんでした(日付全体ではなく、日のみで並べ替えられました)。日付を前処理してdd-mm-yyyyまたはyyyy-mm-ddのいずれかに変換しましたが、うまくいきました!!! (なぜハイフンでは機能するがスラッシュでは機能しないのか?)
Javier Larroulet

array_multisortは、私のjsonファイルをpubdateでソートするために機能した唯一のソートメソッドです。ありがとう。
grc

本当にうまくいきました。ありがとう
Fernando Torres


6

http://us2.php.net/manual/en/function.array-multisort.php 3番目の例を参照してください。

<?php

$data[] = array('volume' => 67, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 1);
$data[] = array('volume' => 85, 'edition' => 6);
$data[] = array('volume' => 98, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 6);
$data[] = array('volume' => 67, 'edition' => 7);

foreach ($data as $key => $row) {
    $volume[$key]  = $row['volume'];
    $edition[$key] = $row['edition'];
}

array_multisort($volume, SORT_DESC, $edition, SORT_ASC, $data);

?>

fyi、unix(1970年からの秒数)またはmysqlタイムスタンプ(YmdHis-20100526014500)を使用する方が、パーサーにとっては簡単ですが、あなたの場合、違いはないと思います。


5

指定されたmysqlの日時フィールドと順序によるレコード/ assoc_arraysの配列のソート:

function build_sorter($key, $dir='ASC') {
    return function ($a, $b) use ($key, $dir) {
        $t1 = strtotime(is_array($a) ? $a[$key] : $a->$key);
        $t2 = strtotime(is_array($b) ? $b[$key] : $b->$key);
        if ($t1 == $t2) return 0;
        return (strtoupper($dir) == 'ASC' ? ($t1 < $t2) : ($t1 > $t2)) ? -1 : 1;
    };
}


// $sort - key or property name 
// $dir - ASC/DESC sort order or empty
usort($arr, build_sorter($sort, $dir));

完全に私が必要なもの。しかし、に変更str_to_upperする必要がありますstrtoupper
ジミーアダロ2016年

4

$array = Array
(
  [0] => Array
   (
    [id] => 2
    [type] => comment
    [text] => hey
    [datetime] => 2010-05-15 11:29:45
   )

 [1] => Array
  (
    [id] => 3
    [type] => status
    [text] => oi
    [datetime] => 2010-05-26 15:59:53
  )

  [2] => Array
   (
    [id] => 4
    [type] => status
    [text] => yeww
    [datetime] => 2010-05-26 16:04:24
   )

   );
   print_r($array);   
   $name = 'datetime';
   usort($array, function ($a, $b) use(&$name){
      return $a[$name] - $b[$name];});

   print_r($array);

4

この問題は、コールバック関数でusort()を使用して簡単に解決できます。カスタム関数を記述する必要はありません。

$your_date_field_name = 'datetime';
usort($your_given_array_name, function ($a, $b) use (&$your_date_field_name) {
    return strtotime($a[$your_date_field_name]) - strtotime($b[$your_date_field_name]);
});

1

私はこの投稿に出くわしましたが、クラス内のアイテムを返すときに時間で並べ替えたいのでエラーが発生しました。

だから私はphp.netのウェブサイトを調べて、これをやる:

class MyClass {
   public function getItems(){
      usort( $this->items, array("MyClass", "sortByTime") );
      return $this->items;
   }
   public function sortByTime($a, $b){
      return $b["time"] - $a["time"];
   }
}

PHP.net Webサイトで非常に役立つ例を見つけることができます

私の配列は次のようになりました:

  'recent' => 
    array
      92 => 
        array
          'id' => string '92' (length=2)
          'quantity' => string '1' (length=1)
          'time' => string '1396514041' (length=10)
      52 => 
        array
          'id' => string '52' (length=2)
          'quantity' => string '8' (length=1)
          'time' => string '1396514838' (length=10)
      22 => 
        array
          'id' => string '22' (length=2)
          'quantity' => string '1' (length=1)
          'time' => string '1396514871' (length=10)
      81 => 
        array
          'id' => string '81' (length=2)
          'quantity' => string '2' (length=1)
          'time' => string '1396514988' (length=10)

1

以下のための'd/m/Y'日付:

usort($array, function ($a, $b, $i = 'datetime') { 
    $t1 = strtotime(str_replace('/', '-', $a[$i]));
    $t2 = strtotime(str_replace('/', '-', $b[$i]));

    return $t1 > $t2;
});

$i配列のインデックスはどこですか


1

関数sortByDateを使用してクラス内でこのように解決された問題をまだ探している人は、以下のコードを参照してください

<?php

class ContactsController 
{
    public function __construct()
    {
    //
    }


    function sortByDate($key)
    {
        return function ($a, $b) use ($key) {
            $t1 = strtotime($a[$key]);
            $t2 = strtotime($b[$key]);
            return $t2-$t1;
        };

    }

    public function index()
    {

        $data[] = array('contact' => '434343434', 'name' => 'dickson','updated_at' =>'2020-06-11 12:38:23','created_at' =>'2020-06-11 12:38:23');
        $data[] = array('contact' => '434343434', 'name' => 'dickson','updated_at' =>'2020-06-16 12:38:23','created_at' =>'2020-06-10 12:38:23');
        $data[] = array('contact' => '434343434', 'name' => 'dickson','updated_at' =>'2020-06-7 12:38:23','created_at' =>'2020-06-9 12:38:23');


        usort($data, $this->sortByDate('updated_at'));

        //usort($data, $this->sortByDate('created_at'));
        echo $data;

    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.