按最近日期对对象数组进行排序
Sort array of objects by closest date
我在 PHP 中有一组对象,只有一个键 - 日期。我有未来的日期,也有过去的日期。我需要按最新日期对它们进行排序。
这是我来自 var_dump()
的数组
array (size=15)
0 =>
object(stdClass)[7852]
public 'date' => string '20200417' (length=8)
1 =>
object(stdClass)[7846]
public 'date' => string '20200302' (length=8)
2 =>
object(stdClass)[7856]
public 'date' => string '20200224' (length=8)
3 =>
object(stdClass)[7853]
public 'date' => string '20200220' (length=8)
4 =>
object(stdClass)[7847]
public 'date' => string '20200213' (length=8)
5 =>
object(stdClass)[7845]
public 'date' => string '20200211' (length=8)
...
有没有办法对此进行排序,以便第一个对象是 20200302,然后是 20200224,依此类推。但未来的日期将在数组的最后。
我试过这个:
usort($arr, function($a, $b) {
return strtotime($b->date) - strtotime($a->date);
});
但是这段代码不关心当前日期,它只是将它们按日期排序。
我还尝试了一种解决方法,从 date('Ymd') - $arr->date
计算间隔并将其设置为对象的一部分,但是 usrot
函数中的 strcmp()
给出几乎相同的结果,因为未来的日期将给出负数和升序负数将排在正数之前。意思是,最近的日期将是第一个,而不是最新的日期。
非常感谢任何帮助。
你需要做的是算出每个日期离今天有多远,并用它来对项目进行排序,可能有更优雅的方法,但这个(我认为)有效。基本上使用 abs()
来确保所有差异都是 +ve 并将每个日期从今天开始...
usort($arr, function($a, $b) {
return (abs(strtotime('today') - strtotime($a->date))
- (abs(strtotime('today') - strtotime($b->date))));
});
Nigel 的回答帮了大忙,但结果参差不齐,有时日期会乱七八糟,我不知道为什么。所以,我想出了一个解决方法,也许它会对互联网上的某个人有所帮助。
我又添加了一个 key/value 到对象 - interval
,我按以下方式计算了此键的值。
$interval_raw = date("Ymd") - get_field('date_nachalo') + 1;
if($interval_raw < 0) {
$interval_raw += 10000;
}
所以,如果我得到一个未来日期的负数,我会加上 10000,也就是提前 30 年,我想这有点过分了,因为没有正常的人类将事件安排到那么遥远的未来。此外,还添加了 + 1
,以便下一个即将到来的日期排在第一位。如果我删除它,那么第一个日期将是过去的日期。基本上,如果今天是 3 月 10 日,最后一个事件是 3 月 1 日,下一个事件是 3 月 11 日,如果没有 + 1
,第一个事件日期将是 3 月 1 日而不是 3 月 11 日。
如果有人知道更优雅的方法,请让全世界知道。
我在 PHP 中有一组对象,只有一个键 - 日期。我有未来的日期,也有过去的日期。我需要按最新日期对它们进行排序。
这是我来自 var_dump()
array (size=15)
0 =>
object(stdClass)[7852]
public 'date' => string '20200417' (length=8)
1 =>
object(stdClass)[7846]
public 'date' => string '20200302' (length=8)
2 =>
object(stdClass)[7856]
public 'date' => string '20200224' (length=8)
3 =>
object(stdClass)[7853]
public 'date' => string '20200220' (length=8)
4 =>
object(stdClass)[7847]
public 'date' => string '20200213' (length=8)
5 =>
object(stdClass)[7845]
public 'date' => string '20200211' (length=8)
...
有没有办法对此进行排序,以便第一个对象是 20200302,然后是 20200224,依此类推。但未来的日期将在数组的最后。
我试过这个:
usort($arr, function($a, $b) {
return strtotime($b->date) - strtotime($a->date);
});
但是这段代码不关心当前日期,它只是将它们按日期排序。
我还尝试了一种解决方法,从 date('Ymd') - $arr->date
计算间隔并将其设置为对象的一部分,但是 usrot
函数中的 strcmp()
给出几乎相同的结果,因为未来的日期将给出负数和升序负数将排在正数之前。意思是,最近的日期将是第一个,而不是最新的日期。
非常感谢任何帮助。
你需要做的是算出每个日期离今天有多远,并用它来对项目进行排序,可能有更优雅的方法,但这个(我认为)有效。基本上使用 abs()
来确保所有差异都是 +ve 并将每个日期从今天开始...
usort($arr, function($a, $b) {
return (abs(strtotime('today') - strtotime($a->date))
- (abs(strtotime('today') - strtotime($b->date))));
});
Nigel 的回答帮了大忙,但结果参差不齐,有时日期会乱七八糟,我不知道为什么。所以,我想出了一个解决方法,也许它会对互联网上的某个人有所帮助。
我又添加了一个 key/value 到对象 - interval
,我按以下方式计算了此键的值。
$interval_raw = date("Ymd") - get_field('date_nachalo') + 1;
if($interval_raw < 0) {
$interval_raw += 10000;
}
所以,如果我得到一个未来日期的负数,我会加上 10000,也就是提前 30 年,我想这有点过分了,因为没有正常的人类将事件安排到那么遥远的未来。此外,还添加了 + 1
,以便下一个即将到来的日期排在第一位。如果我删除它,那么第一个日期将是过去的日期。基本上,如果今天是 3 月 10 日,最后一个事件是 3 月 1 日,下一个事件是 3 月 11 日,如果没有 + 1
,第一个事件日期将是 3 月 1 日而不是 3 月 11 日。
如果有人知道更优雅的方法,请让全世界知道。