我正在尝试使用array_multisort对任何数组进行排序,并且一切正常。但是,根据脚本中的条件,我需要更改选项。所以我到目前为止是:
array_multisort(
$sort1,SORT_ASC,
$sort2,SORT_ASC,
$sort3,SORT_ASC,
$arraytosort
);
而且我想拥有的是这样的:
$dynamicSort = "$sort1,SORT_ASC,$sort2,SORT_ASC,$sort3,SORT_ASC,";
array_multisort(
$dynamicSort,
$arraytosort
);
有什么建议吗?
您可以尝试使用call_user_func_array。但是我以前从未在内置函数上尝试过它。这是一个例子:
$dynamicSort = "$sort1,SORT_ASC,$sort2,SORT_ASC,$sort3,SORT_ASC";
$param = array_merge(explode(",", $dynamicSort), array($arrayToSort))
call_user_func_array('array_multisort', $param)
我在这个答案上也遇到了同样的问题:“参数1应该是数组或排序标志”
对于有相同问题的任何人,请尝试以下方法:
$dynamicSort = array(&$sort1, SORT_ASC, &$sort2, SORT_ASC, &$sort3, SORT_ASC);
$param = array_merge($dynamicSort, array(&$arrayToSort));
call_user_func_array('array_multisort', $param);
[请注意,我已使用对变量“&$”而不是$的引用。这在php 5.3中效果很好,但由于错误可能在5.2中导致错误。
重要的是,发送到call_user_func_array()的数组必须包含only引用;是否通过引用传递数组本身并不重要。我花了一天的大部分时间对此进行故障排除; php.net的函数页面上的示例全部使用了文字数组,这一事实使我进入了此页面:php Bug #49353。问题已解决。
这似乎没有很好的(或一致的)记录,所以这里....
这些不起作用(PHP 5.3.3):
$multisort_array = array($arr1, SORT_DESC, SORT_STRING, $arr2); // array of values
call_user_func_array('array_multisort', $multisort_array); // array passed by value
$multisort_array = array($arr1, SORT_DESC, SORT_STRING, $arr2); // array of values
call_user_func_array('array_multisort', &$multisort_array); // array passed by reference
$multisort_array = array(&$arr1, SORT_DESC, SORT_STRING, &$arr2); // non-constants by reference
call_user_func_array('array_multisort', $multisort_array); // array passed by value
$multisort_array = array(&$arr1, SORT_DESC, SORT_STRING, &$arr2); // non-constants by reference
call_user_func_array('array_multisort', &$multisort_array); // array passed by reference
这些工作:
$sort = array('desc' => SORT_DESC, 'string' => SORT_STRING);
$multisort_array = array(&$arr1, &$sort['desc'], &$sort['string'], &$arr2); // all by reference
call_user_func_array('array_multisort', $multisort_array); // array passed by value
$sort = array('desc' => SORT_DESC, 'string' => SORT_STRING);
$multisort_array = array(&$arr1, &$sort['desc'], &$sort['string'], &$arr2); // all by reference
call_user_func_array('array_multisort', &$multisort_array); // array passed by reference
要添加到现有答案中,只是以为我会添加一些内容。对于将所需的“排序依据”作为逗号分隔的$ _POST变量(或与此相关的任何逗号分隔的变量)的人:
//$_POST["sort_by"] = "column_A DESC, column_B ASC, columns_C DESC";
$sort_bys = explode(",", $_POST["sort_by"]);
$dynamicSort = array();
foreach($sort_bys as $sort_by){
$sort_by2 = trim(str_replace('DESC','',$sort_by));
$direction = (strpos($sort_by, 'DESC') !== false)?SORT_DESC:SORT_ASC;
$$sort_by2 = array_column($array_to_sort, $sort_by2);
$dynamicSort[] = &$$sort_by2;
$dynamicSort[] = $direction;
$dynamicSort[] = SORT_NUMERIC; //or SORT_STRING or SORT_REGULAR ...
}
$param = array_merge($dynamicSort, array(&$array_to_sort));
call_user_func_array('array_multisort', $param);
从PHP5.6开始,您可以使用可变参数技术。只需将所有排序数据和排序逻辑推入索引数组,然后使用splat运算符将参数解压缩为array_multisort()
。在将其放入参数数组之前,请确保要修改的数组可以通过引用进行修改。
下面将参数推入$sortingParams
可以更简洁地写为一个声明,但是我认为以这种方式进行概念化会更容易。这些单独的推送将适合在迭代过程(例如foreach()
)内部使用。
对于用于对父数组进行排序的每一列数据,您可以选择推送零个,一个或两个其他元素以最好地表示排序逻辑。
代码:(Demo)
$array = [
['number' => 2, 'letter' => 'a', 'price' => 9.99],
['number' => 3, 'letter' => 'b', 'price' => 9.99],
['number' => 1, 'letter' => 'c', 'price' => 9.50],
['number' => 1, 'letter' => 'd', 'price' => 10],
['number' => 1, 'letter' => 'e', 'price' => 9.99],
];
$sortingParams[] = array_column($array, 'number'); // 1-dimensional
$sortingParams[] = SORT_ASC; // this is omittable as well because it is assumed (just for demo)
$sortingParams[] = array_column($array, 'price'); // 1-dimensional
$sortingParams[] = SORT_DESC;
$sortingParams[] = SORT_NUMERIC; // this is omittable as well because it is assumed (just for demo)
$sortingParams[] = &$array; // this is the actual master array which should be modified
array_multisort(...$sortingParams); // unpack with splat operator
var_export($array);
输出:
array (
0 =>
array (
'number' => 1,
'letter' => 'd',
'price' => 10,
),
1 =>
array (
'number' => 1,
'letter' => 'e',
'price' => 9.99,
),
2 =>
array (
'number' => 1,
'letter' => 'c',
'price' => 9.5,
),
3 =>
array (
'number' => 2,
'letter' => 'a',
'price' => 9.99,
),
4 =>
array (
'number' => 3,
'letter' => 'b',
'price' => 9.99,
),
)
如果您将动态规则传递给流程,则此技术超级强大。就我而言,我需要从DataTables UI收集过滤器,并将数据重新生成为.csv。我只需要遍历DataTable的订单数据并得出我的规则集-完成。
[与call_user_func_array()
相比,我觉得这种语法更实用。
这里是一个更复杂的实现:Sort array of associative arrays on multiple columns using specified sorting rules