如何按多列对多维数组进行排序?

2021-12-21 00:00:00 multidimensional-array sorting php usort

我正在尝试做与 MySQL 查询相同的操作

I'm trying to do the same as MySQL query

SELECT * FROM table ORDER BY field1, field2, ...

但是使用 php 和一个多维数组:

but with php and a multidimensional array:

$Test = array(
    array("a"=>"004", "n"=>"03"),
    array("a"=>"003", "n"=>"02"),
    array("a"=>"001", "n"=>"02"),
    array("a"=>"005", "n"=>"01"),
    array("a"=>"001", "n"=>"01"),
    array("a"=>"004", "n"=>"02"),
    array("a"=>"003", "n"=>"01"),
    array("a"=>"004", "n"=>"01")
);
function msort(&$array, $keys){
    array_reverse($keys);
    foreach($keys as $key){
        uasort($array, sortByKey);
    }
    //
    function sortByKey($A, $B){

        global $key;

        $a = $A[$key];
        $b = $B[$key];
        if($a==$b) return 0;
        return ($a < $b)? -1 : 1 ;
    }
}
//
msort($Test, array("a","n"));
//
foreach($Test as $t){
    echo('<p>'.$t["a"].'-'.$t["n"].'</p>');
}

我的理论是:如果我对重要性较低"的列进行多次排序,然后对重要性较高"的列进行排序,我将获得类似于上述 MySQL 查询的顺序.

My theory is: if I sort multiple times on columns with "lesser importance" then columns of "greater importance", I'll achieve an order like the above MySQL query.

不幸的是,php 正在返回:

Unfortunately, php is returning:

警告:uasort() 期望参数 2 是一个有效的回调,在第 23 行的/Library/WebServer/Documents/www/teste.array_sort.php 中找不到函数sortByKey"或无效的函数名称"(uasort 行)

Warning: uasort() expects parameter 2 to be a valid callback, function 'sortByKey' not found or invalid function name in /Library/WebServer/Documents/www/teste.array_sort.php on line 23" (uasort line)

这是一个简单的订单功能.我错过了什么?

It's a simple order function. What am I missing?

推荐答案

从根本上说,我们将使用与 此处所述相同的方法,我们只是用可变数量的键来做:

Fundamentally we're going to use the same approach as explained here, we're just going to do it with a variable number of keys:

/**
 * Returns a comparison function to sort by $cmp
 * over multiple keys. First argument is the comparison
 * function, all following arguments are the keys to
 * sort by.
 */
function createMultiKeyCmpFunc($cmp, $key /* , keys... */) {
    $keys = func_get_args();
    array_shift($keys);

    return function (array $a, array $b) use ($cmp, $keys) {
        return array_reduce($keys, function ($result, $key) use ($cmp, $a, $b) {
            return $result ?: call_user_func($cmp, $a[$key], $b[$key]);
        });
    };
}

usort($array, createMultiKeyCmpFunc('strcmp', 'foo', 'bar', 'baz'));
// or
usort($array, createMultiKeyCmpFunc(function ($a, $b) { return $a - $b; }, 'foo', 'bar', 'baz'));

这大约相当于 SQL ORDER BY foo, bar, baz.

That's about equivalent to an SQL ORDER BY foo, bar, baz.

当然,如果每个键都需要不同类型的比较逻辑,并且您不能对所有键使用通用的 strcmp-,那么您将回到相同的代码如此处所述.

If of course each key requires a different kind of comparison logic and you cannot use a general strcmp or - for all keys, you're back to the same code as explained here.

相关文章