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

时间:2011-08-19 21:46:23

标签: php arrays sorting

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

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

通过date密钥,最早的第一个?

5 个答案:

答案 0 :(得分:32)

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

答案 1 :(得分:15)

由于最初的问题是关于对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');

答案 2 :(得分:3)

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

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

答案 3 :(得分:1)

因为你的月份——也可能是你的日子——值不是零填充的,你不能立即将日期作为简单的字符串进行比较。您应该使用 strtotime() 将日期转换为 unix 时间整数——这些将适用于可靠的比较。

此外,不要丢失一级键与其对象之间的关联关系似乎很重要。要对键进行排序和保留,请调用 uasort()。在现代 php 中,spaceship 运算符是进行 3 向比较(返回 -1、0 或 1)的首选实用程序。

代码:

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

这是a demo of both techniques

对于任何排序日期、时间或日期时间值的人来说,这些值可以自然地作为基本字符串进行比较(例如 Y-m-d H:i:sH:im/dY-m-d、等等,然后看this answer for more efficient techniques

答案 4 :(得分:0)

我想扩展arnaud576875和Michael Irigoyen。

对象包含带有Symphony的dateTime。

我不能使用$ a ['date'],因为它不是一个关键数组。

start:
if inputdevice == keyboard 1
    then
        System.Diagnostics.Process.Start(myBatchFileName);
    else
        goto start;

这解决了我的问题