I am trying to sort each Rates
array by Price
from low to high (ascending). I cannot figure it out looking at other solutions.
*Note that there are multiple subarrays like 13188
within the main array.
$array = array(
13188 => array(
'Rates' => array(
0 => array(
'RateName' => 'Standard Rate',
'Price' => 499.56
),
18739 => array(
'RateName' => 'Second Rate',
'Price' => 449.6
)
)
)
)
I want to have this result:
$array = array(
13188 => array(
'Rates' => array(
18739 => array(
'RateName' => 'Second Rate',
'Price' => 449.6
),
0 => array(
'RateName' => 'Standard Rate',
'Price' => 499.56
)
)
)
)
As you can see, the Rates
subarray is sorted by Price
. This means that the Price
of 18739
is lower than the Price
of 0
within the Rates
subarray.
You can use http://php.net/manual/en/function.uasort.php for each elemnts on your arr. That function takes "Callback" ( http://php.net/manual/en/language.types.callable.php ) in which you can describe your rules of conduct.
<?php
$arr = [
13188 => [
'Rates' => [
0 => [
'RatteName' => 'Second Rate',
'Price' => 499.6
],
18739 => [
'RatteName' => 'Second Rate',
'Price' => 499.56
],
1 => [
'RatteName' => 'Second Rate',
'Price' => 15.5
],
2 => [
'RatteName' => 'Second Rate',
'Price' => 14
],
3 => [
'RatteName' => 'Second Rate',
'Price' => 100
]
]
],
13189 => [
'Rates' => [
0 => [
'RatteName' => 'Second Rate',
'Price' => 5
],
18739 => [
'RatteName' => 'Second Rate',
'Price' => 7
],
1 => [
'RatteName' => 'Second Rate',
'Price' => 18.3
],
2 => [
'RatteName' => 'Second Rate',
'Price' => 2
],
3 => [
'RatteName' => 'Second Rate',
'Price' => 22
]
]
],
13140 => [
'Rates' => [
0 => [
'RatteName' => 'Second Rate',
'Price' => 1
],
18739 => [
'RatteName' => 'Second Rate',
'Price' => 13
],
1 => [
'RatteName' => 'Second Rate',
'Price' => 866.17
],
2 => [
'RatteName' => 'Second Rate',
'Price' => 19
],
3 => [
'RatteName' => 'Second Rate',
'Price' => 25
]
]
],
];
foreach($arr as $key => &$arrRates){
$sortArr = $arrRates['Rates'];
uasort($sortArr, function($firstArr, $secondArr){
if ($firstArr['Price'] == $secondArr['Price']) {
return 0;
}
return ($firstArr['Price'] < $secondArr['Price']) ? -1 : 1;
});
$arrRates['Rates'] = $sortArr;
}
echo "<pre>";
print_r($arr);
echo "</pre>";
Array
(
[13188] => Array
(
[Rates] => Array
(
[2] => Array
(
[RatteName] => Second Rate
[Price] => 14
)
[1] => Array
(
[RatteName] => Second Rate
[Price] => 15.5
)
[3] => Array
(
[RatteName] => Second Rate
[Price] => 100
)
[18739] => Array
(
[RatteName] => Second Rate
[Price] => 499.56
)
[0] => Array
(
[RatteName] => Second Rate
[Price] => 499.6
)
)
)
[13189] => Array
(
[Rates] => Array
(
[2] => Array
(
[RatteName] => Second Rate
[Price] => 2
)
[0] => Array
(
[RatteName] => Second Rate
[Price] => 5
)
[18739] => Array
(
[RatteName] => Second Rate
[Price] => 7
)
[1] => Array
(
[RatteName] => Second Rate
[Price] => 18.3
)
[3] => Array
(
[RatteName] => Second Rate
[Price] => 22
)
)
)
[13140] => Array
(
[Rates] => Array
(
[0] => Array
(
[RatteName] => Second Rate
[Price] => 1
)
[18739] => Array
(
[RatteName] => Second Rate
[Price] => 13
)
[2] => Array
(
[RatteName] => Second Rate
[Price] => 19
)
[3] => Array
(
[RatteName] => Second Rate
[Price] => 25
)
[1] => Array
(
[RatteName] => Second Rate
[Price] => 866.17
)
)
)
)
There are two "styles" for ordering your Rates
subarrays in ascending order while preserving keys. The best tool for this job is uasort() because it allows you to perform a customized sort on the array that it is fed. The a
in uasort()
means "preserve the original keys".
The "magic" of the "user-defined sort" is in the second parameter -- a function call. No matter what function you decide to call, uasort()
will be delivering values in sets of two to the function for comparison (I am naming these values $a
and $b
). How you compare these two variables (and in what order you compare them) will determine the outcome of the sort.
I will be using the modern php "spaceship operator" for comparisons, but you may elect to use an older / more verbose set of "greater than, less than, equal to" conditions.
The first method "modifies by reference" with the &
symbol (instead of processing a copy of the array in the foreach loop, and the second method simply overwrites the original array on each iteration by referencing the necessary keys.
Method #1 : "modify by reference"
foreach($array as &$subarray){ // modify $subarray by reference using &
uasort($subarray['Rates'],function($a,$b){
return $a['Price']<=>$b['Price']; // $b<=>$a would mean DESC order
});
}
Method #2 : "iterative overwrite"
foreach($array as $key=>$subarray){ // iterate
$rates=$subarray['Rates']; // isolate the Rates subarray
uasort($rates,function($a,$b){ // sort the Rates subarray
return $a['Price']<=>$b['Price']; // ascending order
});
$array[$key]['Rates']=$rates; // overwrite the original array
}
To clarify a point that is specific to this case, you should NOT use array_multisort() because it will re-index your Rates
subarray (overwrite the original numeric keys starting from zero). For cases when you have associative keys -- go for it... just not this time.
DON'T USE THIS METHOD FOR YOUR CASE:
foreach($array as &$subarray){ // modify $subarray by reference using &
array_multisort(array_column($subarray['Rates'],'Price'),$subarray['Rates']);
}
NOR THIS ONE:
foreach($array as $key=>$subarray){ // iterate and overwrite
$rates=$subarray['Rates'];
array_multisort(array_column($rates,'Price'),$rates);
$array[$key]['Rates']=$rates;
}
Here is a demo page that has all four methods set up so that you can run them and see the output for yourself: Demo Link
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.