PHP 按包含 Y-m-dH: i: s date 的元素对多维数组进行排序

我有一个数组,比如:

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 元素对其进行排序的方法吗?

152111 次浏览

使用 usort()和自定义比较函数:

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

EDIT : 您的数据组织在一个数组数组中。为了更好地区分它们,让我们调用内部数组(数据)记录,这样您的数据实际上就是一个记录数组。

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

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


?>

仅供参考,使用 unix (从1970年开始的秒数)或 mysql 时间戳(YmdHis-20100526014500)对解析器来说会更容易,但我认为在您的情况下没有什么区别。

根据指定的 mysql datetime 字段和顺序对记录/assoc _ array 的数组排序:

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

这应该可以。我通过 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);

我看到了这篇文章,但是我想在返回类中的项目时按时间排序,结果我得到了一个错误。

所以我研究了 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)

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

您可以简单地使用带回调函数的 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]);
});

从 php7你可以使用 宇宙飞船操作员:

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

'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是数组索引

对于那些仍然希望在具有 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;


}
}

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

因为你的 datetime值是用降序格式的单位(YmdHis)和因为每个单位始终用相同数量的字符(4,2,2,2,2,2)表示和因为分隔字符从字符串到字符串都是相同的,你可以简单地从左到右逐个字符地比较它们(自然)。对于格式为(比如说) d/m/Y的日期字符串,这种情况不会发生。

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

示范连结

  • Usort ()按日期列 DESC:

    usort($array, function($a, $b) { return $b['datetime'] <=> $a['datetime']; });
    
  • Usort ()按日期列 ASC:

    usort($array, function($a, $b) { return $a['datetime'] <=> $b['datetime']; });
    
  • Usort ()按日期列 ASC in > = PHP7.4:

    usort($array, fn($a, $b) => $a['datetime'] <=> $b['datetime']);
    
  • Array _ multisort () by date 列 DESC:

     array_multisort(array_column($array, 'datetime'), SORT_DESC, $array);
    
  • Array _ multisort () by date 列 ASC:

    array_multisort(array_column($array, 'datetime'), $array);
    

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

返回文章页面

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

返回文章页面

  • 不使用排序方向常数,因此开发人员必须明白,$a之前的 $b(在飞船操作员的任何一边)意味着 ASC 和 $b之前的 $a意味着 DESC
  • 需要一个自定义函数
  • 可以通过调用 uasort()来调整以保留第一级键

对于那些真正需要解析日期或日期时间字符串的人,因为它的格式不允许进行即时字符串比较,这里是 专门用来解释那项任务的注意事项的答案