【问题标题】:Possible to pass a closure to usort in PHP?可以在 PHP 中将闭包传递给 usort?
【发布时间】:2011-08-23 10:16:48
【问题描述】:

我有一个数组排序函数如下:

public function sortAscending($accounts)
{
    function ascending($accountA, $accountB) {
        if ($accountA['AmountUntilNextTarget'] == $accountB['AmountUntilNextTarget']) {
            return 0;
        }
        return ($accountA['AmountUntilNextTarget'] < $accountB['AmountUntilNextTarget']) ? -1 : 1;
    }
    usort($accounts, $ascending);

    return $accounts;
}

显然这并不理想,因为它对要搜索的键进行了硬编码。我想我会通过将密钥作为参数传递给外部函数来使其通用,但是这超出了内部函数的范围。我试图通过使用可以访问参数的闭包而不是内部函数来解决这个问题,如下所示:

public function sortAscending($accounts, $key)
{
    $ascending = function($accountA, $accountB) {
        if ($accountsA[$key] == $accountB[$key]) {
            return 0;
        }
        return ($accountA[$key] < $accountB[$key]) ? -1 : 1;
    }
    usort($accounts, $ascending);

    return $accounts;
}

但是 usort() 只接受一个函数名,所以这不起作用。谁能看到(更好的?)实现这一目标的方法?

【问题讨论】:

  • usort 接受一个 callback 参数,它可以是一个闭包。代码中明显的错误是函数定义后缺少;。也许这就是错误的原因。
  • 除了缺少;$key 也不在你的关闭范围内。你应该使用它:$ascending = function($acciontA, $accountB) use($key) { ...

标签: php arrays sorting closures usort


【解决方案1】:

闭包也可以继承变量 从父范围。任何此类 变量必须在 函数头。继承变量 从父范围不一样 就像使用全局变量一样。全球的 变量存在于全局范围内, 无论如何都是一样的 功能正在执行。父母 闭包的作用域是 宣布关闭的(不是 一定是它被调用的函数 来自)。

  • 另请注意,定义闭包并将其分配给变量是正常的赋值操作,因此您需要在闭包的} 之后加上;

进行这些更改后,您的代码将如下所示(并且应该可以正常工作):

public function sortAscending($accounts, $key)
{
    $ascending = function($accountA, $accountB) use ($key) {
        if ($accountsA[$key] == $accountB[$key]) {
            return 0;
        }
        return ($accountA[$key] < $accountB[$key]) ? -1 : 1;
    };
    usort($accounts, $ascending);

    return $accounts;
}

【讨论】:

  • 感谢 bazmegakapa 和其他人的快速回复,这真的很有帮助。抱歉,我没有注意到那个丢失的分号,小学生的错误。
【解决方案2】:

为了澄清这一点 - 并将其编码为闭包 - 并使用 PHP7 spaceship 运算符 - 并更正第一个答案第 4 行中的错字,请跳过 $ascending 变量:

public function sortAscending($accounts, $key)
{
    usort($accounts, function($accA, $accB) use ($key) {
        return $accA[$key] <=> $accB[$key];
    });
    return $accounts;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-22
    • 2019-07-03
    • 2012-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多