-2

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.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Preamas
  • 1
  • 7
  • Use [`krsort()`](http://php.net/manual/en/function.krsort.php). – axiac Feb 09 '18 at 10:22
  • Please google before asking: https://stackoverflow.com/questions/2477496/php-sort-array-by-subarray-value – Auris Feb 09 '18 at 10:24
  • Possible duplicate of [PHP Sort Array By SubArray Value](https://stackoverflow.com/questions/2477496/php-sort-array-by-subarray-value) – Auris Feb 09 '18 at 10:25

2 Answers2

0

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
                        )

                )

        )

)
Viktor
  • 1,532
  • 6
  • 22
  • 61
0

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

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
  • Thanks for your help. The thing is that `<=>` only works in PHP 7+. – Preamas Feb 12 '18 at 08:56
  • Are you able to downgrade the comparison for earlier versions of php? (For your project?) – mickmackusa Feb 12 '18 at 08:58
  • I am working with the language level 5.6, I am able to upgrade and downgrade. If I upgrade to language level 7, will this affect my code? – Preamas Feb 12 '18 at 09:02
  • I certainly recommend using the highest version that you can for many reasons. But it may cause hiccups elsewhere. Check everything after upgrading. – mickmackusa Feb 12 '18 at 09:05