Возможно ли передать замыкание на usort в PHP? - PullRequest
5 голосов
/ 11 мая 2011

У меня есть функция сортировки массива следующим образом:

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 () принимает только имя функции, поэтому это нет работа.Кто-нибудь может увидеть (лучше?) Способ достижения этого?

Ответы [ 2 ]

14 голосов
/ 11 мая 2011

Замыкания также могут наследовать переменные из родительской области.Любые такие переменные должны быть объявлены в заголовке функции.Наследование переменных из родительской области - это не то же самое, что использование глобальных переменных.Глобальные переменные существуют в глобальной области видимости, которая является одинаковой независимо от того, какую функцию выполняет.Родительская область видимости замыкания - это функция, в которой было объявлено замыкание (не обязательно функция, из которой оно было вызвано).

  • Обратите внимание, что определение замыкания и его назначениеПеременная - это обычная операция присваивания, поэтому вам понадобится ; после закрытия } закрытия.

После внесения этих изменений ваш код будет выглядеть так (и должен нормально работать):

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;
}
2 голосов
/ 26 февраля 2019

Чтобы прояснить это - и кодировать его как замыкание - и использовать оператор космического корабля PHP7 - и исправить опечатку в строке 4 первого ответа, пропустите переменную $ ascending:

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