动态 array_multisort() 而不调用已弃用的函数 create_function()
Dynamic array_multisort() without calling deprecated function create_function()
我的旧 php5 代码中有这个函数,它将接受可变数量的参数并根据参数执行排序:
function array_alternate_multisort(){
$arguments = func_get_args();
$arrays = $arguments[0];
for ($c = (count($arguments)-1); $c > 0; $c--)
{
if (in_array($arguments[$c], array(SORT_ASC , SORT_DESC)))
{
continue;
}
$compare = create_function('$a,$b','return strcasecmp($a["'.$arguments[$c].'"], $b["'.$arguments[$c].'"]);');
usort($arrays, $compare);
if ($arguments[$c+1] == SORT_DESC)
{
$arrays = array_reverse($arrays);
}
}
return $arrays ;
}
我这样称呼它:
$alliances = array_alternate_multisort($alliances, "output", SORT_DESC, "score", SORT_DESC);
如何在不调用 create_function()
的情况下用函数替换它?
您可以改用 anonymous function:
$compare = function ($a, $b) use ($arguments, $c) {
return strcasecmp($a[$arguments[$c]], $b[$arguments[$c]]);
};
未测试但应该足够接近
use
关键字允许您从函数内的父作用域继承变量。
首先,我会争辩说,如果你有能力将它硬编码到你的脚本中:
$alliances = array_alternate_multisort($alliances, "output", SORT_DESC, "score", SORT_DESC);
然后你可以很容易地完全废弃你的自定义函数并写下这个:
代码:(Demo)
array_multisort(...[
array_column($alliances, 'output'),
SORT_DESC,
array_column($alliances, 'score'),
SORT_DESC,
&$alliances
]);
这将完成您的自定义函数将做的所有事情,而且无需引入任何自定义函数。
这是一种非常简洁、完全原生且可立即阅读的技术。使用这意味着:
- 您不会将脚本仅限于
SORT_ASC
和 SORT_DESC
;对于特定场景,还有其他有用的排序标志。
- 如果您想使用
SORT_ASC
(默认排序标志),您可以选择省略排序方向参数。
- 您可以像其他本机排序函数一样通过引用修改输入数组。
现在超出上述范围的任何事情都会引入不必要的卷积。为了使这个假设(同样,我不赞同)的演示保持简单,我会坚持要求排序方向标志,就像您的原始代码片段中那样。
代码:(Demo)
function array_alternate_multisort($array, ...$args) {
foreach ($args as $i => $arg) {
$sortParams[] = $i & 1 ? $arg : array_column($array, $arg);
}
$sortParams[] = &$array;
array_multisort(...$sortParams);
return $array;
}
& 1
是按位奇数检查。如果索引为奇数,则将常量推入 $sortParams
否则将列数据推入 $sortParams
.
此答案属于使用 splat 运算符将参数解压缩到 array_multisort()
调用中的一系列类似答案。
- array_multisort and dynamic variable options
- Sort array of associative arrays on multiple columns using specified sorting rules
我的旧 php5 代码中有这个函数,它将接受可变数量的参数并根据参数执行排序:
function array_alternate_multisort(){
$arguments = func_get_args();
$arrays = $arguments[0];
for ($c = (count($arguments)-1); $c > 0; $c--)
{
if (in_array($arguments[$c], array(SORT_ASC , SORT_DESC)))
{
continue;
}
$compare = create_function('$a,$b','return strcasecmp($a["'.$arguments[$c].'"], $b["'.$arguments[$c].'"]);');
usort($arrays, $compare);
if ($arguments[$c+1] == SORT_DESC)
{
$arrays = array_reverse($arrays);
}
}
return $arrays ;
}
我这样称呼它:
$alliances = array_alternate_multisort($alliances, "output", SORT_DESC, "score", SORT_DESC);
如何在不调用 create_function()
的情况下用函数替换它?
您可以改用 anonymous function:
$compare = function ($a, $b) use ($arguments, $c) {
return strcasecmp($a[$arguments[$c]], $b[$arguments[$c]]);
};
未测试但应该足够接近
use
关键字允许您从函数内的父作用域继承变量。
首先,我会争辩说,如果你有能力将它硬编码到你的脚本中:
$alliances = array_alternate_multisort($alliances, "output", SORT_DESC, "score", SORT_DESC);
然后你可以很容易地完全废弃你的自定义函数并写下这个:
代码:(Demo)
array_multisort(...[
array_column($alliances, 'output'),
SORT_DESC,
array_column($alliances, 'score'),
SORT_DESC,
&$alliances
]);
这将完成您的自定义函数将做的所有事情,而且无需引入任何自定义函数。
这是一种非常简洁、完全原生且可立即阅读的技术。使用这意味着:
- 您不会将脚本仅限于
SORT_ASC
和SORT_DESC
;对于特定场景,还有其他有用的排序标志。 - 如果您想使用
SORT_ASC
(默认排序标志),您可以选择省略排序方向参数。 - 您可以像其他本机排序函数一样通过引用修改输入数组。
现在超出上述范围的任何事情都会引入不必要的卷积。为了使这个假设(同样,我不赞同)的演示保持简单,我会坚持要求排序方向标志,就像您的原始代码片段中那样。
代码:(Demo)
function array_alternate_multisort($array, ...$args) {
foreach ($args as $i => $arg) {
$sortParams[] = $i & 1 ? $arg : array_column($array, $arg);
}
$sortParams[] = &$array;
array_multisort(...$sortParams);
return $array;
}
& 1
是按位奇数检查。如果索引为奇数,则将常量推入$sortParams
否则将列数据推入$sortParams
.
此答案属于使用 splat 运算符将参数解压缩到 array_multisort()
调用中的一系列类似答案。
- array_multisort and dynamic variable options
- Sort array of associative arrays on multiple columns using specified sorting rules