I have the following Eloquent collection:
[
[
'id' => 60902,
'source' => 'M',
'price' => 10.15
],
[
'id' => 57348,
'source' => 'A',
'price' => 12.00
],
[
'id' => 54472,
'source' => 'A',
'price' => 12.00
],
]
I'm trying to sort it with this code:
$items = $items->sort(function (Item $a, Item $b) {
if ($a->source == 'A') {
if ($b->source == 'M' || ($b->source == 'A' && $a->price < $b->price)) {
return 1;
} elseif ($b->source == 'A' && $a->price == $b->price) {
return 0;
} else {
return -1;
}
} else {
if ($b->source == 'A' || ($b->source == 'M' && $b->price < $a->price)) {
return -1;
} elseif ($b->source == 'M' && $b->price == $a->price) {
return 0;
} else {
return 1;
}
}
});
However, the original sort order of $items
is always the same before and after. The first item (60902) in the list should have been moved from the beginning to the end.
I ran an Xdebug trace and can see that item 60902 returned -1
in the sorting function and the other two items returned 0
because they are equivalent to each other.
This is how I expect the collection to look after sorting:
[
[
'id' => 57348,
'source' => 'A',
'price' => 12.00
],
[
'id' => 54472,
'source' => 'A',
'price' => 12.00
],
[
'id' => 60902,
'source' => 'M',
'price' => 10.15
]
]
Where is my logic messed up here?
The solution to this was ridiculously simple...I just needed to swap 1
and -1
when returning the sort value to get the results I wanted.
New code looks like this:
$items = $items->sort(function (Item $a, Item $b) {
if ($a->source == 'A') {
if ($b->source == 'M' || ($b->source == 'A' && $a->price < $b->price)) {
return -1;
} elseif ($b->source == 'A' && $a->price == $b->price) {
return 0;
} else {
return 1;
}
} else {
if ($b->source == 'A' || ($b->source == 'M' && $b->price < $a->price)) {
return 1;
} elseif ($b->source == 'M' && $b->price == $a->price) {
return 0;
} else {
return -1;
}
}
});