Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will $a > $b ever break usort() with an array of integers?

Tags:

php

sorting

In almost every example of usort() the logic seems to be that you should return -1, 0, or 1, making the new spaceship operator ideal. Before php7 the most basic example goes like this:

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

I'm having trouble understanding why not simply use:

usort($arr, function($a, $b) {
    return $a > $b;
}

Will this ever break and if so under what conditions?

I've also read How the usort() sorting algorithm works?, compared results from both methods outlined above for the life of me I can't understand why the suggested method will ever return a different result.

like image 451
Eaten by a Grue Avatar asked Dec 06 '25 16:12

Eaten by a Grue


1 Answers

The current sorting implementation used in usort can be found here: https://github.com/php/php-src/blob/ba298725d194f753c0220bd9ac482e3d257a9ddc/Zend/zend_sort.c#L317

As you can see it only uses the > 0 comparison, eg

while (cmp(pivot, i) > 0) {

If php core team for some reason changes the implementation to use == 0 or < 0, then your solution would break (because it does not differentiate between those cases).

Given that documentation makes no claims on how the sorting would ever be implemented - it's safe to assume that every function that does not follow the protocol - is incorrect and is not guaranteed to work.

In general - for unstable sorting just "whether $a is greater than $b" is enough. Some programming languages/libraries employ it. Eg: in Go you only need to implement a simple Less function that returns a boolean.

like image 156
zerkms Avatar answered Dec 11 '25 12:12

zerkms



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!