This question is actually inspired from another one here on SO and I wanted to expand it a bit.
Having an associative array in PHP is it possible to sort its values, but where the values are equal to preserve the original key order, using one (or more) of PHP's built in sort function?
Here is a script I used to test possible solutions (haven't found any):
<?php
header('Content-type: text/plain');
for($i=0;$i<10;$i++){
$arr['key-'.$i] = rand(1,5)*10;
}
uasort($arr, function($a, $b){
// sort condition may go here //
// Tried: return ($a == $b)?1:($a - $b); //
// Tried: return $a >= $b; //
});
print_r($arr);
?>
Pitfall: Because the keys are ordered in the original array, please don't be tempted to suggest any sorting by key to restore to the original order. I made the example with them ordered to be easier to visually check their order in the output.
This is a solution using which you can achieve stable sort in usort function
For completeness sake, you should also check out the Schwartzian transform:
The default sort algorithm of PHP works fine with arrays, because of this:
If you want to use your own sorting criteria you can use
uasort()
as well:Since PHP does not support stable sort after PHP 4.1.0, you need to write your own function.
This seems to do what you're asking: http://www.php.net/manual/en/function.usort.php#38827
Also, you may find this forum thread interesting.
Just to complete the responses with some very specific case. If the array keys of
$array
are the default one, then a simplearray_values(asort($array))
is sufficient (here for example in ascending order)For future reference, I've put a set of stable sort variants of builtin PHP functions on Github: https://github.com/vanderlee/PHP-stable-sort-functions, based on @Jack's solution and a few other tricks.
array_multisort
comes in handy, just use an ordered range as second array ($order
is just temporary, it serves to order the equivalent items of the first array in its original order):Output
I used test data with not-ordered keys to demonstrate that it works correctly. Nonetheless, here is the output your test script:
Downside
It only works with predefined comparisons, you cannot use your own comparison function. The possible values (second parameter of
array_multisort()
) are: