首页 > 解决方案 > 对嵌套数组进行排序时,PHP usort 函数返回不正确的结果

问题描述

我有一个像这样的多维数组:

$sort_arr = array(
    array(
        '07',
        '45'
    ),
    array(
        '07',
        '44'
    ),
    array(
        '07',
        '46'
    ),
    array(
        '22',
        '64'
    )
);

我需要按降序对它进行两次排序,以使第一列优先。为此,首先对第二列进行排序,这样当对第一列进行排序时,它将在适当的位置覆盖结果

我创建了这个 usort 函数:

$order = array(1, 0);

foreach($order as $col){
    usort($sort_arr, function($a, $b) use ($col){
        return strnatcmp($b[$col], $a[$col]);//b before a - descending order
    });
    var_dump($sort_arr);
}

预期输出:

array(4) {
    [0]=>
    array(2) {
        '22',
        '64'
    }
    [1]=>
    array(2) {
        '07',
        '46'
    }
    [2]=>
    array(2) {
        '07',
        '45'
    }
    [3]=>
    array(2) {
        '07',
        '44'
    }//Result of first sort

array(4) {
    [0]=>
    array(2) {
        '22',
        '64'
    }
    [1]=>
    array(2) {
        '07',
        '46'
    }
    [2]=>
    array(2) {
        '07',
        '45'
    }
    [3]=>
    array(2) {
        '17',
        '44'
    }//Final result

实际输出:

array(4) {
    [0]=>
    array(2) {
        '22',
        '64'
    }
    [1]=>
    array(2) {
        '07',
        '46'
    }
    [2]=>
    array(2) {
        '07',
        '45'
    }
    [3]=>
    array(2) {
        '07',
        '44'
    }//Result of first sort - correct

array(4) {
    [0]=>
    array(2) {
        '22',
        '64'
    }
    [1]=>
    array(2) {
        '07',
        '44'
    }
    [2]=>
    array(2) {
        '07',
        '46'
    }
    [3]=>
    array(2) {
        '07',
        '45'
    }//Final result - incorrect

PHP 版本:5.6。

在 7.0 上,返回正确的结果。

我无法更新 PHP 版本。

标签: phparraysusort

解决方案


我想你有问题因为If two members compare as equal, their relative order in the sorted array is undefined. doc可能从 5.6 到 7 版本的 php

为了防止这样的混乱,您可以使用 hack 进行一次性排序:

<?php

$sort_arr = array(
    array(
        '07',
        '45'
    ),
    array(
        '07',
        '44'
    ),
    array(
        '07',
        '46'
    ),
    array(
        '22',
        '64'
    )
);

$order = array(1, 0);

usort($sort_arr, function($a, $b) use ($order){
    $sum = 0;
    foreach($order as $key => $col){
        $sum += strnatcmp($b[$col], $a[$col]) * pow(10, ($key+1));
    }
    return $sum;
});
var_dump($sort_arr);

你可以在这里查看不同版本的结果

关于这些东西的更多数据


推荐阅读