PHP Mengurutkan array multidimensi berdasarkan elemen yang mengandung tanggal

113

Saya memiliki array seperti:

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
    )

)

Adakah yang bisa menyarankan cara untuk mengurutkan / memesan ini berdasarkan elemen datetime?

Tim
sumber

Jawaban:

206

Gunakan usort()dan fungsi perbandingan kustom:

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

EDIT : Data Anda diatur dalam array array. Untuk lebih membedakannya, mari kita panggil catatan array (data) bagian dalam, sehingga data Anda benar-benar adalah array catatan.

usortakan meneruskan dua record ini ke fungsi perbandingan yang diberikan date_compare()pada satu waktu. date_comparekemudian mengekstrak "datetime"bidang dari setiap rekaman sebagai stempel waktu UNIX (bilangan bulat), dan mengembalikan perbedaannya, sehingga hasilnya adalah 0jika kedua tanggal sama, angka positif jika yang pertama ( $a) lebih besar atau nilai negatif jika argumen kedua ( $b) lebih besar. usort()menggunakan informasi ini untuk mengurutkan array.

Ferdinand Beyer
sumber
1
dalam contoh ini, apakah $ array perlu berisi elemen $ a dan $ b? - im mendapatkan kesalahan fungsi perbandingan tidak valid
Tim
Tidak, $adan $bakan menahan array di dalamnya $array. Pastikan Anda tidak salah mengeja nama fungsi.
Ferdinand Beyer
Saya tidak yakin saya mengerti. Dalam contoh saya, saya memiliki 3 array dalam array - saya telah mengkonfirmasi namanya, masih mendapatkan fungsi perbandingan yang tidak valid
Tim
Lihat penjelasan yang saya tambahkan. Saya menguji kodenya dan berfungsi dengan baik untuk saya!
Ferdinand Beyer
9
Saya tidak tahu CodeIgniter, tetapi apakah Anda mendefinisikan fungsi di dalam kelas? Daripada Anda harus mendefinisikannya di luar kelas atau menggunakan argumen callback yang berbeda:, usort($array, array($this, "date_compare"))jadi usort()itu adalah fungsi / metode kelas. Lihat juga: php.net/manual/en/…
Ferdinand Beyer
45

Ini seharusnya berhasil. Saya mengubah tanggal menjadi waktu unix melalui strtotime.

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

Versi satu baris akan menggunakan beberapa metode array:

array_multisort(array_map('strtotime',array_column($originalArray,'datetime')),
                SORT_DESC, 
                $originalArray);
Dave Tidak Ada
sumber
Ini bekerja dengan baik. Cukup ganti: $ originalArray dengan nama array multi-dimensi Anda. Dan ganti: 'datetime' dengan nama bidang sub-larik Anda untuk tanggal. Terima kasih.
Washere
1
solusi ini berhasil bagi saya. opsi pengurutan juga bagus (SORT_ASC atau SORT_DESC). Terima kasih banyak.
Andras Barth
bekerja dengan baik dengan satu peringatan kecil (entah itu, atau saya melakukan sesuatu yang salah) ... bidang tanggal yang perlu saya sortir memiliki tanggal dalam format hh / bb / tttt atau tttt / mm / hh (dengan garis miring). Dalam hal ini, pengurutan tidak berfungsi karena beberapa alasan (diurutkan hanya berdasarkan hari, bukan seluruh tanggal). Saya memproses tanggal sebelumnya untuk mengubahnya menjadi hh-bb-tttt atau tttt-bb-hh dan itu berhasil jadi terima kasih !!! (ada ide tentang mengapa itu bekerja dengan tanda hubung tetapi tidak garis miring?)
Javier Larroulet
array_multisort adalah satu-satunya metode pengurutan yang berfungsi untuk mengurutkan file json saya berdasarkan pubdate. Terima kasih.
grc
Bekerja dengan sangat baik untuk saya, terima kasih
Fernando Torres
41

Dari php7 Anda dapat menggunakan operator Spaceship :

usort($array, function($a, $b) {
  return new DateTime($a['datetime']) <=> new DateTime($b['datetime']);
});
Federkun
sumber
6

http://us2.php.net/manual/en/function.array-multisort.php lihat contoh ketiga:

<?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, menggunakan unix (detik dari 1970) atau cap waktu mysql (YmdHis - 20100526014500) akan lebih mudah untuk parser tetapi saya pikir dalam kasus Anda tidak ada bedanya.

Toby
sumber
5

Menyortir array record / assoc_arrays berdasarkan bidang waktu mysql yang ditentukan dan berdasarkan urutan:

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));
falko
sumber
Benar-benar apa yang saya butuhkan. Tapi harus berubah str_to_uppermenjadi strtoupper.
Jimmy Adaro
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);
Ajit Kumar
sumber
4

Anda cukup memecahkan masalah ini menggunakan usort () dengan fungsi callback. Tidak perlu menulis fungsi kustom apa pun.

$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]);
});
Faisal
sumber
1

Saya menemukan posting ini tetapi saya ingin mengurutkan berdasarkan waktu ketika mengembalikan item di dalam kelas saya dan saya mendapat kesalahan.

Jadi saya meneliti situs web php.net dan akhirnya melakukan ini:

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

Anda dapat menemukan contoh yang sangat berguna di situs web PHP.net

Array saya terlihat seperti ini:

  '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)
Bata Abadi
sumber
1

Untuk 'd/m/Y'tanggal:

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

    return $t1 > $t2;
});

dimana $iindeks array

Borjovsky
sumber
1

Bagi mereka yang masih mencari pemecahannya dengan cara ini di dalam kelas dengan fungsi sortByDate, lihat kode di bawah ini

<?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;

    }
}
Dickson Godwin
sumber