使用指定的排序选项对多个"列"(键)上的多维数组阵列进行排序

JCo*_*obb 6 php arrays sorting multidimensional-array

我希望能够在多个列上对多维数组进行排序.为了进一步复杂化,我希望能够为每个键/列设置特定的排序选项.我有类似DB查询的结果,但实际上并不是来自一个,因此需要在PHP而不是SQL中对其进行排序.

Array
(
    [0] => Array
        (
            [first_name] => Homer
            [last_name] => Simpson
            [city] => Springfield
            [state] => Unknown
            [zip] => 66735
        )

    [1] => Array
        (
            [first_name] => Patty
            [last_name] => Bouvier
            [city] => Scottsdale
            [state] => Arizona
            [zip] => 85250
        )

    [2] => Array
        (
            [first_name] => Moe
            [last_name] => Szyslak
            [city] => Scottsdale
            [state] => Arizona
            [zip] => 85255
        )

    [3] => Array
        (
            [first_name] => Nick
            [last_name] => Riviera
            [city] => Scottsdale
            [state] => Arizona
            [zip] => 85255
        )

)
Run Code Online (Sandbox Code Playgroud)

我希望能够对它进行排序,类似于使用数据库查询可以完成的任务.哦,有时候需要用数字来指定列/键.

我想到的是类似的东西:

$sortOptions = array( array( 'city', SORT_ASC, SORT_STRING ),
                      array( 'zip', SORT_DESC, SORT_NUMERIC),
                      array( 2, SORT_ASC, SORT_STRING) // 2='last_name'
                    );
$sorter = new MultiSort($data, $sortOptions );
$sortedData = $sorter->getSortedArray() ;
print_r( $jmsSorted);
Run Code Online (Sandbox Code Playgroud)

我想最终得到的是:

Array
(
    [0] => Array
        (
            [first_name] => Nick
            [last_name] => Riviera
            [city] => Scottsdale
            [state] => Arizona
            [zip] => 85255
        )

    [1] => Array
        (
            [first_name] => Moe
            [last_name] => Szyslak
            [city] => Scottsdale
            [state] => Arizona
            [zip] => 85255
        )

    [2] => Array
        (
            [first_name] => Patty
            [last_name] => Bouvier
            [city] => Scottsdale
            [state] => Arizona
            [zip] => 85250
        )

    [3] => Array
        (
            [first_name] => Homer
            [last_name] => Simpson
            [city] => Springfield
            [state] => Unknown
            [zip] => 66735
        )

)
Run Code Online (Sandbox Code Playgroud)

更新:我认为理想情况下,解决方案会导致动态创建

array_multisort( $city, SORT_ASC, SORT_STRING, $zip, SORT_DESC, SORT_NUMERIC, $last_name, SORT_ASC, SORT_STRING, $inputArray);
Run Code Online (Sandbox Code Playgroud)

问题是我不想在那里"硬编码"那些关键名称.我尝试基于Example#3创建一个解决方案,从array_multisort()最终使用的文档中排序数据库结果,array_multisort()但我似乎无法找到使用我动态构建的参数列表的方法array_multisort().

我的尝试是将这些参数"链接"成一个数组然后

call_user_func_array( 'array_multisort', $functionArgs);
Run Code Online (Sandbox Code Playgroud)

这导致了

Warning: Parameter 2 to array_multisort() expected to be a reference, value given in...
Run Code Online (Sandbox Code Playgroud)

JCo*_*obb 1

这是我最终决定能够对多维数组进行排序的方法。上面的两个答案都很好,但我也在寻找灵活的东西。

\n\n

我绝对不认为\xe2\x80\x99t 认为有任何一个\xe2\x80\x9cright\xe2\x80\x9d 答案,但这正是适合我的需求并且灵活的。

\n\n

@link正如您从我的评论中看到的_usortByMultipleKeys()那样,它改编自 PHP 手册中的评论,目前似乎不存在,但我相信http://www.php.net/manual/en/function.usort .php#104398是原始评论的新版本。我还没有探索使用这个新建议。

\n\n
/**\n * Sort the resultSet.\n *\n * Usage: $sortOptions = array(\n *          \'section\', // Defaults to SORT_ASC\n *          \'row\' => SORT_DESC,\n *          \'retail_price\' => SORT_ASC);\n *        $results->sortResults($sortOptions);\n *\n * @param array $sortOptions    An array of sorting instructions\n */\npublic function sortResults(array $sortOptions)\n{\n    usort($this->_results, $this->_usortByMultipleKeys($sortOptions));\n}\n\n\n/**\n * Used by sortResults()\n *\n * @link http://www.php.net/manual/en/function.usort.php#103722\n */\nprotected function _usortByMultipleKeys($key, $direction=SORT_ASC)\n{\n    $sortFlags = array(SORT_ASC, SORT_DESC);\n    if (!in_array($direction, $sortFlags)) {\n        throw new InvalidArgumentException(\'Sort flag only accepts SORT_ASC or SORT_DESC\');\n    }\n    return function($a, $b) use ($key, $direction, $sortFlags) {\n        if (!is_array($key)) { //just one key and sort direction\n            if (!isset($a->$key) || !isset($b->$key)) {\n                throw new Exception(\'Attempting to sort on non-existent keys\');\n            }\n            if ($a->$key == $b->$key) {\n                return 0;\n            }\n            return ($direction==SORT_ASC xor $a->$key < $b->$key) ? 1 : -1;\n        } else { //using multiple keys for sort and sub-sort\n            foreach ($key as $subKey => $subAsc) {\n                //array can come as \'sort_key\'=>SORT_ASC|SORT_DESC or just \'sort_key\', so need to detect which\n                if (!in_array($subAsc, $sortFlags)) {\n                    $subKey = $subAsc;\n                    $subAsc = $direction;\n                }\n                //just like above, except \'continue\' in place of return 0\n                if (!isset($a->$subKey) || !isset($b->$subKey)) {\n                    throw new Exception(\'Attempting to sort on non-existent keys\');\n                }\n                if ($a->$subKey == $b->$subKey) {\n                    continue;\n                }\n                return ($subAsc==SORT_ASC xor $a->$subKey < $b->$subKey) ? 1 : -1;\n            }\n            return 0;\n        }\n    };\n}\n
Run Code Online (Sandbox Code Playgroud)\n