PHP按包含日期的元素对多维数组进行排序

Tim*_*Tim 107 php arrays sorting datetime

我有一个数组,如:

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
    )

)
Run Code Online (Sandbox Code Playgroud)

任何人都可以建议一种基于日期时间元素排序/订购的方法吗?

Fer*_*yer 190

使用usort()和自定义比较功能:

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

编辑:您的数据按阵列数组织.为了更好地区分这些,我们调用内部数组(数据)记录,以便您的数据确实是一个记录数组.

usort将这些记录中的两个一次传递给给定的比较函数date_compare(). date_compare然后将"datetime"每个记录的字段作为UNIX时间戳(整数)提取,并返回差值,这样0如果两个日期相等则结果为,如果第一个($a)较大则为正数,如果是,则为负值第二个参数($b)更大. usort()使用此信息对数组进行排序.

  • 我不知道CodeIgniter,但你是在一个类中定义函数吗?你要么必须在类外定义它,要么使用不同的回调参数:`usort($ array,array($ this,"date_compare"))`,这样`usort()`就知道它是一个类函数/方法.另见:http://www.php.net/manual/en/language.pseudo-types.php#language.types.callback (8认同)

Fed*_*kun 35

从php7您可以使用Spaceship运算符:

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


小智 34

这应该工作.我通过strtotime将日期转换为unix时间.

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


mic*_*usa 7

大多数早期答案都未能承认将日期时间值与简单字符串进行比较的可用快捷方式。其他意识到这strtotime()是不必要的答案并没有说明他们为什么这样做……所以我会的。

因为您的datetime值的格式是按大小递减的单位 ( Y, m, d, H, i, s) 并且因为每个单位一致地用相同数量的字符表示 (4, 2, 2, 2, 2, 2) 并且因为分隔字符都是字符串之间是相同的,您可以简单地从左到右(自然地)逐个字符地比较它们。对于格式为 的日期字符串来说,情况并非如此d/m/Y

有两个函数非常适合此任务,我将演示这两个函数的 ASC 和 DESC 版本。

演示链接

所有这些技术都通过引用进行修改,因此该函数没有提供真正有价值的返回值。

array_multisort():

  • 不需要自定义函数
  • 它确实需要通过某种循环机制来隔离日期时间列
  • 它将丢失数字键,但幸运的是它们对于这个问题没有价值

usort():

  • 不使用排序方向常量,因此开发人员必须了解$abefore $b(在飞船运算符的任一侧)表示 ASC,$bbefore$a表示 DESC
  • 需要自定义函数
  • 可以通过调用来调整以保留第一级uasort()密钥

对于真正需要解析日期或日期时间字符串的人,因为其格式不允许即时字符串比较,这里有一个答案专门用于解释该任务的注意事项


Tob*_*oby 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);

?>
Run Code Online (Sandbox Code Playgroud)

fyi,使用unix(1970年的秒)或mysql时间戳(YmdHis - 20100526014500)对于解析器来说会更容易,但我认为在你的情况下它没有任何区别.


小智 6

$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);
Run Code Online (Sandbox Code Playgroud)


Fai*_*sal 6

您可以使用带有回调函数的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]);
});
Run Code Online (Sandbox Code Playgroud)


fal*_*lko 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));
Run Code Online (Sandbox Code Playgroud)