首页 文章

如何通过乘法键对多维数组进行排序?

提问于
浏览
0

我正在尝试使用多维数组执行与mySQL查询“SELECT * FROM table ORDER BY field1,field2,...”相同的操作:

$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查询的顺序排序 .

但是php正在返回“警告:uasort()期望参数2是有效的回调函数,函数'sortByKey'未找到或者在第23行的/Library/WebServer/Documents/www/teste.array_sort.php中找到无效的函数名”(uasort)线)

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

3 回答

  • 6

    从根本上说,我们将使用与解释here相同的方法,我们将使用可变数量的键来执行此操作:

    /**
     * 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 .

    当然,如果每个键需要一种不同类型的比较逻辑,并且您不能对所有键使用通用 strcmp- ,那么您将返回与解释here相同的代码 .

  • 0

    这是我写的一些类似的代码:

    uasort($array,function($a,$b) {
        return strcmp($a['launch'],$b['launch'])
            ?: strcmp($a['tld'],$b['tld'])
            ?: strcmp($a['sld'],$b['sld']);
    });
    

    它有点滥用这个事实,即负数是真实的(只有零是假的)首先比较 launch ,然后是 tld ,然后是 sld . 您应该能够轻松地根据您的需求进行调整 .

  • 4

    这将完成这项工作,感谢您的贡献!

    function mdsort(&$array, $keys){
    
        global $KeyOrder;
    
        $KeyOrder = $keys;
        uasort($array, cmp);    
    }
    function cmp(array $a, array $b) {
    
        global $KeyOrder;
    
        foreach($KeyOrder as $key){
            $res = strcmp($a[$key], $b[$key]);
            if($res!=0) break;
        }
        return $res;
    }
    //
    mdsort($Test, array("a","n"));
    

    这段代码有点难看,但我相信它可能会更好 - 也许是一个类来解决将数组传递给“cmp”函数的问题 . 但它是一个起点,你可以使用它与任意数量的键进行排序 .

相关问题