PHP จัดเรียงอาร์เรย์หลายมิติตามองค์ประกอบที่มีวันที่


115

ฉันมีอาร์เรย์เช่น:

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
    )

)

ใครช่วยแนะนำวิธีเรียงลำดับ / เรียงลำดับตามองค์ประกอบวันเวลาได้ไหม

คำตอบ:


207

ใช้usort()และฟังก์ชันเปรียบเทียบแบบกำหนดเอง:

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

แก้ไข : ข้อมูลของคุณถูกจัดเรียงในอาร์เรย์ของอาร์เรย์ เพื่อให้แยกความแตกต่างได้ดีขึ้นเราเรียกระเบียนภายในอาร์เรย์ (ข้อมูล) เพื่อให้ข้อมูลของคุณเป็นอาร์เรย์ของระเบียน

usortจะส่งสองระเบียนเหล่านี้ไปยังฟังก์ชันเปรียบเทียบที่กำหนดdate_compare()ในแต่ละครั้ง date_compareจากนั้นแยก"datetime"ฟิลด์ของแต่ละเร็กคอร์ดเป็นการประทับเวลา UNIX (จำนวนเต็ม) และส่งกลับความแตกต่างดังนั้นผลลัพธ์จะเป็น0ถ้าวันที่ทั้งสองเท่ากันเป็นจำนวนบวกถ้าวันแรก ( $a) มีค่ามากกว่าหรือเป็นค่าลบหาก อาร์กิวเมนต์ที่สอง ( $b) มีขนาดใหญ่กว่า usort()ใช้ข้อมูลนี้เพื่อจัดเรียงอาร์เรย์


1
ในตัวอย่างนี้ $ array จำเป็นต้องมีองค์ประกอบ $ a และ $ b หรือไม่ - ฉันได้รับข้อผิดพลาดฟังก์ชันการเปรียบเทียบที่ไม่ถูกต้อง
Tim

Nope, $aและจะถืออาร์เรย์ภายใน$b $arrayตรวจสอบให้แน่ใจว่าคุณไม่ได้สะกดชื่อฟังก์ชันผิด
Ferdinand Beyer

ฉันไม่แน่ใจว่าฉันเข้าใจ ในตัวอย่างของฉันฉันมี 3 อาร์เรย์ในอาร์เรย์ - ฉันได้ยืนยันชื่อแล้ว แต่ยังคงได้รับฟังก์ชันการเปรียบเทียบที่ไม่ถูกต้อง
Tim

ดูคำอธิบายที่ฉันเพิ่ม ฉันทดสอบโค้ดแล้วและมันใช้งานได้ดีสำหรับฉัน!
Ferdinand Beyer

10
ฉันไม่รู้จัก CodeIgniter แต่คุณกำลังกำหนดฟังก์ชันภายในคลาสหรือไม่? กว่าที่คุณจะต้องกำหนดนอกคลาสหรือใช้อาร์กิวเมนต์เรียกกลับที่แตกต่างกัน: usort($array, array($this, "date_compare"))เพื่อให้usort()รู้ว่ามันเป็นฟังก์ชัน / วิธีการของคลาส ดูเพิ่มเติมที่: php.net/manual/en/…
เฟอร์ดินานด์เบเยอร์

46

สิ่งนี้ควรใช้งานได้ ฉันแปลงวันที่เป็นเวลา unix ผ่าน strtotime

  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' ด้วยชื่อของฟิลด์อาร์เรย์ย่อยของคุณสำหรับวันที่ ขอบคุณ
นี่

1
วิธีนี้ทำได้ดีสำหรับฉัน ตัวเลือกการจัดเรียงก็ยอดเยี่ยมเช่นกัน (SORT_ASC หรือ SORT_DESC) ขอบคุณมาก.
Andras Barth

ทำงานได้อย่างสวยงามด้วยข้อแม้เล็ก ๆ หนึ่งข้อ (ไม่อย่างนั้นหรือฉันทำอะไรผิดพลาด) ... ฟิลด์วันที่ที่ฉันต้องการจัดเรียงตามมีวันที่ในรูปแบบ 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 ดูตัวอย่างที่สาม:

<?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 timestamp (YmdHis - 20100526014500) จะง่ายกว่าสำหรับ parser แต่ฉันคิดว่าในกรณีของคุณมันไม่แตกต่างกัน


5

การเรียงลำดับอาร์เรย์ของเร็กคอร์ด / Assoc_arrays ตามฟิลด์วันที่และเวลาของ mysql ที่ระบุและตามลำดับ:

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.
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

คุณสามารถแก้ปัญหานี้ได้โดยใช้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

อาร์เรย์ของฉันมีลักษณะดังนี้:

  '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.