Can't seem to get my head around of sorting laravel collection so empty / null data would end up being last. ( bit confused about usort )
Pretty much all I have is bunch of times / timestamps that need to be ordered. Some rows may not have for that column.
I would like data to appear ASC / ascending while empty/null data is shown last.
$collection->sortBy('timestamp') sorts nicely but doesn't know how to deal with empty fields.
Table looks like this.
$data = $data->sort(function($a, $b) use ($sortBy) {
if ($a->{$sortBy} and $b->{$sortBy}) return 0;
return ($a->{$sortBy} > $b->{$sortBy}) ? -1 : 1;
});
Random code I tried from the internet, which I can't get to work correctly.
$sortBy contains a field name to sort by ( since it may change )
Faulty code deals with empty / null data but its out of order.

Have to use sort() with a closure. Below will sort timestamp ASC with NULL at the end.
$sorted = $collection->sort(function ($a, $b) {
if (!$a->timestamp) {
return !$b->timestamp ? 0 : 1;
}
if (!$b->timestamp) {
return -1;
}
if ($a->timestamp == $b->timestamp) {
return 0;
}
return $a->timestamp < $b->timestamp ? -1 : 1;
});
Try:
$collection->sortBy('-timestamp')
Does it work?
I had a similar issue. In my case, the time attribute of a $result might be NULL. It acts as if NULL is 0 (as int) and that's expected behavior. But I also wanted to sort the collection by leaving NULL last.
$collection->sortBy(function ($result) {
if ($result['time'] === NULL) {
return PHP_INT_MAX;
}
return $result['time'];
});
You can achieve this simply by returning an value higher in the alphabetical order compared to all other values in the array. i.e. PHP_INT_MAX to be safe. This will make sure all the results where the time equals NULL are at the end of the array.