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
    )

)

谁能建议一种基于datetime元素对其进行排序/排序的方法?

Answers:


205

使用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)2010年

不会,$a并将$b数组保存在中$array。确保您没有拼写错误的函数名称。
费迪南德·拜尔

我不确定我是否理解。在我的例子,我有3个数组的数组中-我已经证实了名称,仍然得到无效的比较函数
蒂姆

请参阅我添加的说明。我测试了代码,对我来说很好用!
费迪南德·拜尔

9
我不知道CodeIgniter,但是您是否在类中定义函数?比您不得不在类外部定义它或使用其他回调参数:usort($array, array($this, "date_compare")),这样就usort()知道它是一个类函数/方法。参见:php.net/manual/en/...
费迪南德拜尔

44

这应该工作。我通过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”替换为日期的子数组字段的名称。谢谢。
washere

1
这个解决方案对我来说很好。sort选项也很棒(SORT_ASC或SORT_DESC)。非常感谢。
安德拉斯·巴特

可以很好地解决一个小警告(或者是,或者我做错了)...我需要排序的日期字段的日期格式为dd / mm / yyyy或yyyy / mm / dd(带斜线)。在这种情况下,由于某种原因,排序无法正常工作(仅按日期排序,而不按整个日期排序)。我对日期进行了预处理,将其转换为dd-mm-yyyy或yyyy-mm-dd,它的工作原理非常感谢!!!(关于为什么它可以使用连字符而不使用斜杠的任何想法?)
哈维尔·拉鲁莱特

array_multisort是唯一可以按发布日期对json文件进行排序的排序方法。谢谢。
GRC

工作对我很好,谢谢
托雷斯

41

从php7开始,您可以使用Spaceship运算符

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

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时间戳(YmdHis-20100526014500)对于解析器来说会更容易,但是我认为在您的情况下这没有什么区别。


5

按指定的mysql datetime字段和顺序对记录/ 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_upperstrtoupper
吉米·阿达罗

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数组索引在哪里


0

对于那些仍在使用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;

    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.