usort changing Array's order

2019-05-07 03:00发布

问题:

I have a usort function with a single line: return 0.
I tried to use it on an Array of stdClass objects, and it changes
their order, how is that possible?

回答1:

The property you assume is called stability: A stable sorting algorithm will not change the order of elements that are equal.

php's sorting functions are not stable (because non-stable sorts may be slightly faster). From the documentation of usort:

If two members compare as equal, their order in the sorted array is undefined.

If you want a stable sorting algorithm, you must implement it yourself.



回答2:

It's because that function means "I really don't care how they are sorted, they are equal to me". With this simple sample I receive reversed array:

function sortaaa($a,$b) {return 0;}
$array = array(1,2,3,4,5);
usort($array,"sortaaa");
var_dump($array);
//prints array(5) { [0]=> int(5) [1]=> int(4) [2]=> int(3) [3]=> int(2) [4]=> int(1) }

So it looks like PHP loops the array in reverse order in function usort. So, note the usort manual states that

If two members compare as equal, their order in the sorted array is undefined.



回答3:

If you're looking for a quick solution for a stable usort, you could use uksort like in the following example:

<?php

uksort($array, function ($ak, $bk) use ($array) {
    $a = $array[$ak];
    $b = $array[$bk];

    if ($a['foo'] === $b['foo']) 
        return $ak - $bk;

    return $a['foo'] > $b['foo'] ? 1 : -1;
});

This works as expected only if the initial indices (keys) of $array are in ascending order.



标签: php usort