I have an array that looks similar to this:
Array
(
[0] => stdClass Object
(
[Leasing] => 12939.74
[Name] => Jeremy
[Rental] => 0
[Sales] => 56603.13
[Total] => 69542.87
)
[1] => stdClass Object
(
[Leasing] => 0
[Name] => Shaun
[Rental] => 0
[Sales] => 58590
[Total] => 58590
)
[2] => stdClass Object
(
[Leasing] => 0
[Name] => Lindsay
[Rental] => 0
[Sales] => 22951.97
[Total] => 22951.97
)
[3] => stdClass Object
(
[Leasing] => 0
[Name] => Sally
[Rental] => 1200
[Sales] => 21624.9
[Total] => 22824.9
)
[4] => stdClass Object
(
[Leasing] => 0
[Name] => House
[Rental] => 0
[Sales] => 16235.81
[Total] => 16235.81
)
[5] => stdClass Object
(
[Leasing] => 5298.85
[Name] => Bill
[Rental] => 1200
[Sales] => 0
[Total] => 6498.85
)
)
Currently, the array is sorted by total using this:
usort($data, function ($a, $b) {
return $b->Total - $a->Total;
});
Now, I need to be able to ALWAYS have the person with [Name] => House
to the top of the array. My thoughts are that I can leave it sorted by Total
(because I still need it that way) and then take the element with the House value and put it at the start of the array. I can take a particular KEY and put it at the top, but the KEY's may change depending on who has the highest total. How can I always put the person named House
at the top of the array?
This should work:
usort($data, function ($a, $b) {
if ($a->Name != "House" && $b->Name == "House") {
return 1;
} elseif ($a->Name == "House" && $b->Name != "House") {
return -1;
} else {
return $b->Total - $a->Total;
}
});
From PHP: usort - Manual:
The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.
In this case, return 1
tells the sorting function that House
is greater than any other value, and -1
that House
is lesser than any other value.
Your requirements:
Name
column -- position House
valued rows before non-House
valued rows.Total
column DESC.From PHP7, the spaceship operator (<=>
) makes the scripting the sorting rules very clean by evaluating arrays of rules (reading the elements from left to right).
To sort House
rows first, evaluate each object's Name
string to be identical to House
. false
evaluations will be treated as 0
and true
evaluations will be treated as 1
. By writing the $b
data on the left side of the operator, descending sorting is implemented. The House
object will be the only object to evaluate as true
, and because it is the first sorting condition, it will take priority as the first object in the array of objects.
For the other objects that that do not contain House
, the second sorting condition is evaluated. By writing $b
's Total
value on the left side and the $a
's Total
values on the right side, descending sorting is again used -- this puts objects with higher totals before objects with lower totals.
Code: (Demo)
usort(
$objects,
fn($a, $b) =>
[$b->Name === 'House', $b->Total]
<=>
[$a->Name === 'House', $a->Total]
);
For completeness, you can also use array_multisort()
but it will be less efficient than usort()
in this case because multiple function calls will be necessary to prepare the sorting columns. (Demo)
array_multisort(
array_map(fn($obj) => $obj->Name !== 'House', $objects), // ASC puts falses before trues
array_column($objects, 'Total'),
SORT_DESC,
$objects
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With