PHP Sắp xếp một mảng nhiều chiều theo phần tử chứa ngày tháng


113

Tôi có một mảng như:

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
    )

)

Có ai có thể đề xuất cách sắp xếp / sắp xếp thứ tự này dựa trên phần tử datetime không?

Câu trả lời:


206

Sử dụng usort()và một chức năng so sánh tùy chỉnh:

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

CHỈNH SỬA : Dữ liệu của bạn được sắp xếp thành một mảng mảng. Để phân biệt chúng tốt hơn, hãy gọi các bản ghi mảng (dữ liệu) bên trong, để dữ liệu của bạn thực sự là một mảng bản ghi.

usortsẽ chuyển hai bản ghi này tới hàm so sánh đã cho date_compare()tại một thời điểm. date_comparesau đó trích xuất "datetime"trường của mỗi bản ghi dưới dạng dấu thời gian UNIX (một số nguyên) và trả về sự khác biệt, do đó kết quả sẽ là 0nếu cả hai ngày bằng nhau, một số dương nếu ngày đầu tiên ( $a) lớn hơn hoặc giá trị âm nếu đối số thứ hai ( $b) lớn hơn. usort()sử dụng thông tin này để sắp xếp mảng.


1
trong ví dụ này, mảng $ có cần phải chứa các phần tử $ a và $ b không? - tôi nhận được lỗi chức năng so sánh không hợp lệ
Tim

Không, $a$bsẽ giữ các mảng bên trong $array. Đảm bảo rằng bạn không viết sai chính tả tên hàm.
Ferdinand Beyer

tôi không chắc là tôi hiểu. Trong ví dụ của tôi, tôi có 3 mảng trong mảng - Tôi đã xác nhận tên, vẫn nhận được hàm so sánh không hợp lệ
Tim

Xem giải thích tôi đã thêm. Tôi đã thử nghiệm mã và nó hoạt động tốt đối với tôi!
Ferdinand Beyer

9
Tôi không biết CodeIgniter, nhưng bạn có đang xác định hàm bên trong một lớp không? Ngoài ra, bạn phải xác định nó bên ngoài lớp hoặc sử dụng một đối số gọi lại khác:, usort($array, array($this, "date_compare"))để usort()biết rằng đó là một hàm / phương thức của lớp. Xem thêm: php.net/manual/en/…
Ferdinand Beyer

45

Điều này sẽ hoạt động. Tôi đã chuyển đổi ngày thành giờ unix qua strtotime.

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

Phiên bản một lớp lót sẽ sử dụng nhiều phương thức mảng:

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

Điều này hoạt động tuyệt vời. Chỉ cần thay thế: $ originalArray bằng tên của mảng đa chiều của bạn. Và thay thế: 'datetime' bằng tên của trường mảng phụ của bạn cho ngày. Cảm ơn.
đây

1
giải pháp này đang làm tốt cho tôi. tùy chọn sắp xếp cũng tuyệt vời (SORT_ASC hoặc SORT_DESC). Cảm ơn rất nhiều.
Andras Barth

hoạt động tuyệt vời với một thông báo nhỏ (hoặc đó, hoặc tôi đang làm sai điều gì đó) ... trường ngày tôi cần sắp xếp có ngày ở định dạng dd / mm / yyyy hoặc yyyy / mm / dd (có dấu gạch chéo). Trong trường hợp đó, việc sắp xếp không hoạt động vì một số lý do (chỉ được sắp xếp theo ngày, không phải cả ngày). Tôi đã xử lý trước ngày tháng để chuyển đổi chúng thành dd-mm-yyyy hoặc yyyy-mm-dd và nó hoạt động rất hiệu quả, cảm ơn !!! (bất kỳ ý tưởng về lý do tại sao nó hoạt động với dấu gạch nối nhưng không chém?)
Javier Larroulet

array_multisort là phương thức sắp xếp duy nhất hoạt động để sắp xếp tệp json của tôi theo pubdate. cảm ơn.
grc

Làm việc rất tốt cho tôi, cảm ơn
Fernando Torres

41

Từ php7, bạn có thể sử dụng toán tử Spaceship :

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

6

http://us2.php.net/manual/en/ Chức năng.array-multisort.php xem ví dụ thứ ba:

<?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, sử dụng dấu thời gian unix (giây từ năm 1970) hoặc mysql (YmdHis - 20100526014500) sẽ dễ dàng hơn cho trình phân tích cú pháp nhưng tôi nghĩ trong trường hợp của bạn, nó không có gì khác biệt.


5

Sắp xếp mảng bản ghi / assoc_arrays theo trường datetime của mysql được chỉ định và theo thứ tự:

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

Hoàn toàn là những gì tôi cần. Nhưng phải đổi str_to_upperthành 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);

4

Bạn có thể giải quyết vấn đề này một cách đơn giản bằng cách sử dụng usort () với hàm gọi lại. Không cần phải viết bất kỳ chức năng tùy chỉnh nào.

$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

Tôi đã xem qua bài đăng này nhưng tôi muốn sắp xếp theo thời gian khi trả lại các mục trong lớp của mình và tôi đã gặp lỗi.

Vì vậy, tôi nghiên cứu trang web php.net và kết thúc việc này:

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

Bạn có thể tìm thấy các ví dụ rất hữu ích trong trang web PHP.net

Mảng của tôi trông như thế này:

  '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

Đối với các 'd/m/Y'ngày:

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

    return $t1 > $t2;
});

nơi $ilà chỉ số mảng


1

Đối với những người vẫn đang tìm cách giải quyết nó theo cách này bên trong một lớp có hàm sortByDate, hãy xem đoạn mã bên dưới

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

    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.