I have seen other examples, such as:
PHP Sort Array By SubArray Value
The responses there were great, and I expect to incorporate the sortBySubValue
part of the solution proposed by @Pigalev Pavel.
In my use case though, I have an extra level of sub-array, and when I pass in my array, it does not get sorted...
My array structure is:
$players = array(
array(
"name" => "Woods",
"countback" => array(
"9" => 17,
"6" => 11,
"3" => 6,
"1" => 2
)
),
array(
"name" => "Spieth",
"countback" => array(
"9" => 17,
"6" => 12,
"3" => 4,
"1" => 2
)
),
array(
"name" => "McIlroy",
"countback" => array(
"9" => 17,
"6" => 12,
"3" => 5,
"1" => 1
)
),
array(
"name" => "Johnson",
"countback" => array(
"9" => 17,
"6" => 12,
"3" => 5,
"1" => 2
)
)
);
Where the parent array is sorted by the order of the countback
sub-array. The expected final order should be:
- Johnson, winner because the 4th array value (2) is highest in final comparison
- McIlroy, 2nd as the 4th array value (1) is lower
- Speech, 3rd as the 3rd array value (4) is lower than the remainders
- Woods, lowest as 2nd array value (11) is lower than the others.
What changes need to be made to the function provided by @Pigalev Pavel?
/**
* @param array $array
* @param string $value
* @param bool $asc - ASC (true) or DESC (false) sorting
* @param bool $preserveKeys
* @return array
* */
function sortBySubValue($array, $value, $asc = true, $preserveKeys = false)
{
if (is_object(reset($array))) {
$preserveKeys ? uasort($array, function ($a, $b) use ($value, $asc) {
return $a->{$value} == $b->{$value} ? 0 : ($a->{$value} <=> $b->{$value}) * ($asc ? 1 : -1);
}) : usort($array, function ($a, $b) use ($value, $asc) {
return $a->{$value} == $b->{$value} ? 0 : ($a->{$value} <=> $b->{$value}) * ($asc ? 1 : -1);
});
} else {
$preserveKeys ? uasort($array, function ($a, $b) use ($value, $asc) {
return $a[$value] == $b[$value] ? 0 : ($a[$value] <=> $b[$value]) * ($asc ? 1 : -1);
}) : usort($array, function ($a, $b) use ($value, $asc) {
return $a[$value] == $b[$value] ? 0 : ($a[$value] <=> $b[$value]) * ($asc ? 1 : -1);
});
}
return $array;
}
If I print_r($players);
at the end of my PHP script, the array remains in the original order.
UPDATE & RESOLVED
Following comments provided, the issue was that I have printed the original array ($players
), without allowing the function to update the original variable (by reference). the other option is to store it in a new variable returned by the function itself, as:
$sortedPlayers = sortBySubValue($players, 'countback', false);