按日期字段对对象数组进行排序

问题描述 投票:0回答:6

如何重新排列这样的对象数组:

 [495] => stdClass Object
        (
         [date] => 2009-10-31 18:24:09
         ...
        )
 [582] => stdClass Object
        (
         [date] => 2010-2-11 12:01:42
         ...
        )
 ...

date
键,最早的在前?

php arrays sorting
6个回答
53
投票
usort($array, function($a, $b) {
    return strtotime($a['date']) - strtotime($b['date']);
});

或者如果您没有 PHP 5.3:

function cb($a, $b) {
    return strtotime($a['date']) - strtotime($b['date']);
}
usort($array, 'cb');

24
投票

由于最初的问题是关于对 stdClass() 对象的数组进行排序,因此如果 $a 和 $b 是对象,以下代码将起作用:

usort($array, function($a, $b) {
    return strtotime($a->date) - strtotime($b->date);
});

或者如果您没有 PHP 5.3:

function cb($a, $b) {
    return strtotime($a->date) - strtotime($b->date);
}
usort($array, 'cb');

4
投票

我想扩展

arnaud576875
的答案。我遇到了同样的问题,但是使用了 DateTime 对象。这就是我能够完成同样的事情的方式。

usort($array, function($a, $b) {
    return $a['date']->format('U') - $b['date']->format('U');
});

2
投票

由于您的月份(可能还有您的日期)值不是用零填充的,因此您无法立即将日期作为简单字符串进行比较。您应该使用

strtotime()
将日期转换为 unix 时间整数——这些将适合可靠的比较。

此外,不要丢失第一级键及其对象之间的关联关系似乎很重要。要排序并保留密钥,请调用

uasort()
。在现代 PHP 中,spaceship 运算符是进行 3 向比较的首选实用程序(返回 -1、0 或 1)。

即使二维数组是数组的数组而不是对象的数组,下面的所有方法都将同样工作(您只需将

->date
语法更改为
['date']

代码:

uasort(
    $array,
    function($a, $b) {
        return strtotime($a->date) <=> strtotime($b->date);
    }
);

或者在PHP7.4中,有箭头函数语法:

uasort(
    $array,
    fn($a, $b) => strtotime($a->date) <=> strtotime($b->date)
);

u*sort()
的主体中使用函数调用的唯一小缺点是,它将执行多于 n 组的函数调用来打破联系并以其他方式确定正确的顺序。另一种避免这些冗余函数调用的排序技术是
array_multisort()
。它可以被输入一列已执行了 n 函数调用的数据——这实际上使其更加高效。然而,这个排序函数有它自己的警告——它会丢失第一级的数字键。对于本案来说,这可能不是一个可以容忍的损失。

代码:

array_multisort(
    array_map('strtotime', array_column($array, 'date')),
    $array
);

这是这两种技术的演示

对于任何对日期、时间或日期时间值进行排序的人来说,这些值可以作为基本字符串进行自然比较(所谓的 Big-endian 格式,例如

Y-m-d H:i:s
H:i
m/d
Y-m-d
等) .,然后查看此答案以获得更有效的技术


0
投票

我想扩展 arnaud576875 和 Michael Irigoyen。

与 Symphony 包含 dateTime 的对象存在同样的问题。

我无法使用 $a['date'] 因为它不是键数组。

usort($verifications, function($a, $b) {
   return $a->getDate()->format('U') - $b->getDate()->format('U');
});

这解决了我的问题


0
投票

当使用 DateTime 对象作为实体的属性时,这对我有用:

$myArray = $entityRepository->findAll();

usort($myArray, function($a, $b) {
    return $a->getDate()->getTimestamp() - $b->getDate()->getTimestamp();
        });
© www.soinside.com 2019 - 2024. All rights reserved.