如何在多维数组中使用第4级值对第3级子阵列进行排序?

时间:2018-02-09 10:16:37

标签: php sorting multidimensional-array

我正在尝试将每个Rates数组按Price从低到高(升序)排序。我无法理解其他解决方案。

*请注意,主阵列中有多个子阵列,如13188

$array = array(
    13188 => array(
        'Rates' => array(
            0 => array(
                       'RateName' => 'Standard Rate',
                       'Price' => 499.56
                 ),
            18739 => array(
                       'RateName' => 'Second Rate',
                       'Price' => 449.6
                 )
        )
    )
)

我希望得到这样的结果:

$array = array(
    13188 => array(
        'Rates' => array(
            18739 => array(
                       'RateName' => 'Second Rate',
                       'Price' => 449.6
                 ),
            0 => array(
                       'RateName' => 'Standard Rate',
                       'Price' => 499.56
                 )
        )
    )
)

如您所见,Rates子阵列按Price排序。这意味着Price的{​​{1}}低于18739子阵列中Price的{​​{1}}。

2 个答案:

答案 0 :(得分:0)

你可以在你的arr上为每个元素使用http://php.net/manual/en/function.uasort.php。该功能采用“回调”(http://php.net/manual/en/language.types.callable.php),您可以在其中描述您的行为准则。

<?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
                        )

                )

        )

)

答案 1 :(得分:0)

在保留密钥的同时,以升序顺序排序Rates子阵列有两种“样式”。这项工作的最佳工具是uasort(),因为它允许您对输入的阵列执行自定义排序。 a中的uasort()表示“保留原始密钥”。

“用户定义排序”的“魔力”在第二个参数 - 函数调用中。无论您决定拨打什么功能,uasort()都会将两个值的值传递给函数进行比较(我将这些值命名为$a$b)。如何比较这两个变量(以及你比较它们的顺序)将决定排序的结果。

我将使用现代php“太空飞船运营商”进行比较,但您可以选择使用较旧/更详细的“大于,小于,等于”条件。

第一种方法“使用&符号”通过引用修改“(而不是在foreach循环中处理数组的副本,第二种方法通过引用必要的键简单地覆盖每次迭代的原始数组)

方法#1 :“按引用修改”

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
    });
}

方法#2 :“迭代覆盖”

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
}

为了澄清特定于这种情况的观点,您不应该使用array_multisort(),因为它会重新索引您的Rates子阵列(从零开始覆盖原始数字键)。对于你有关联键的情况 - 去吧......就在这个时候。

请勿将此方法用于您的案例:

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;
}

这是一个演示页面,它设置了所有四种方法,以便您可以运行它们并自己查看输出:Demo Link