Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to have a stable sort in PHP with arsort()?

i need to sort an array in php based on value, array use some numbers for keys and values, for example like this:

$a = array(70 => 1 ,82 => 5  ,61 => 3 ,55 => 1 ,34 => 2 ,53 => 2 ,21 => 4 ,13 => 5);

i like to sort it like this:

Array
(
    [82] => 5
    [13] => 5
    [21] => 4
    [61] => 3
    [34] => 2
    [53] => 2
    [70] => 1
    [55] => 1
)

i used arsort and it worked, but there is a problem because this function make change defult sorted keys and sort array to:

Array
(
    [13] => 5
    [82] => 5
    [21] => 4
    [61] => 3
    [53] => 2
    [34] => 2
    [55] => 1
    [70] => 1
)
like image 910
Vahid Avatar asked Oct 01 '12 15:10

Vahid


People also ask

What is Asort () and arsort ()?

Definition and UsageThe arsort() function sorts an associative array in descending order, according to the value. Tip: Use the asort() function to sort an associative array in ascending order, according to the value.

How do you sort the array in descending order predefine PHP function?

PHP - Sort Functions For Arrays sort() - sort arrays in ascending order. rsort() - sort arrays in descending order. asort() - sort associative arrays in ascending order, according to the value.

What does Uasort () function returns on failure?

The uasort( ) function returns true on success or false on failure.

What is the use of sort () function in PHP?

Definition and Usage The sort() function sorts an indexed array in ascending order. Tip: Use the rsort() function to sort an indexed array in descending order.


3 Answers

Construct a new array whose elements are the original array's keys, values, and also position:

$temp = array();
$i = 0;
foreach ($array as $key => $value) {
  $temp[] = array($i, $key, $value);
  $i++;
}

Then sort using a user-defined order that takes the original position into account:

uasort($temp, function($a, $b) {
 return $a[2] == $b[2] ? ($a[0] - $b[0]) : ($a[2] < $b[2] ? 1 : -1);
});

Finally, convert it back to the original associative array:

$array = array();
foreach ($temp as $val) {
  $array[$val[1]] = $val[2];
}
like image 177
Barmar Avatar answered Sep 27 '22 16:09

Barmar


This is because the sort family of functions are not stable. If you need the sort to be stable then you either have to implement it yourself, or iterate over the sorted result and "correct" the positions of the elements using array_splice.

like image 34
Jon Avatar answered Sep 27 '22 17:09

Jon


For 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 @Barmar's solution and a few other tricks.

like image 21
Martijn Avatar answered Sep 27 '22 15:09

Martijn