Reputation: 336
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.
Upvotes: 3
Views: 8464
Reputation: 2683
Similar to Mr. Speelman's solution, but as a shorter PHP 7.4+ version:
$collection->sortBy(fn($e) => $e->timestamp ?: PHP_INT_MAX)
Upvotes: 1
Reputation: 11949
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.
Upvotes: 3
Reputation: 71
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;
});
Upvotes: 7
Reputation: 2553
I assume your timestamp
is unix timestamp.
You can sort it like this :
$sorted = $collection->sortByDesc('timestamp');
Upvotes: -3