1

usort allows custom inline functions and variables to be used with them:

eg

    usort($arr, function($a, $b) use ($key) {
        return strcmp($a[$key], $b[$key]);
    });

usort also allows the sort functions to be defined separately

eg

function cmp($a, $b) {
    if ($a == $b) {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
}
usort($arr, 'cmp');

I have a large comparison function that I want to define separately and not as an inline function. How do I pass a variable to usort and cmp?

  • 1
    How about this https://stackoverflow.com/questions/8230538/pass-extra-parameters-to-usort-callback. You'll basically create your own sort function that will execute usort and be responsible for passing variables to it as needed – Buttered_Toast May 16 '23 at 07:46
  • Please share more details. Anything not working with `use`? – Nico Haase May 16 '23 at 07:46
  • @NicoHaase When I try: ``` // Comparison function function cmp($a, $b) { // TODO: special handling for $c if ($a == $b) { return 0; } return ($a < $b) ? -1 : 1; } // Array to be sorted $array = array('a' => 4, 'b' => 8, 'c' => -1, 'd' => -9, 'e' => 2, 'f' => 5, 'g' => 3, 'h' => -4); $c = "c"; // Sort and print the resulting array usort($array, 'cmp') use $c; print_r($array); ``` I get:PHP Parse error: syntax error, unexpected token "use" in usort_cmp.php on line 17 Parse error: syntax error, unexpected token "use" in usort_cmp.php on line 17 – HealerLolCat May 16 '23 at 07:51
  • 1
    Please add all clarification to your question by editing it. Also, `use` is aprt of the function definition, not of the function call – Nico Haase May 16 '23 at 07:57

1 Answers1

2

usort second argument expects a callable - Any argument that can be called will be executed with the two arguments.

// Function:
$cmp = function($a, $b) { return $a <=> $b; }
usort($arr, $cmp);

// Arrow Function:
$cmp = fn($a, $b) => $a<=>$b;
usort($arr, $cmp);

// Class member:
class Tools {
    static function cmp($a, $b)
    {
        return $a <=> $b;
    }
}
usort($arr, [Tools::class, "cmp"]);

And so on....

For extra arguments, you can use the use keyword as part of the function declaration.

I suggest wrapping the usort procedure you want. This makes the code cleaner and more manageable:


function my_sort(array &$arr, bool $space = true) {
    usort($arr, function($a, $b) use ($space) {
       return $space ? $a <=> $b : $a < $b;
    });
} 
my_sort($arr, false);

Or with an Arrow function:


function my_sort(array &$arr, bool $space = true) {
    usort($arr, fn($a, $b) => $space ? $a <=> $b : $a < $b);
} 
my_sort($arr, false);

Shlomi Hassid
  • 6,500
  • 3
  • 27
  • 48