Reputation: 1
Why does the usort function in the following snippet sort the matrix not only by the values of the 'num' keys in descending order, but then also sorts the elements with equal values of the 'num' keys by the values of the 'lett' keys in ascending order?How can I make it sort by only what is given in the body of the function?
<?php
$mtx = [["num"=>1,"lett"=>"f"],
["num"=>3,"lett"=>"b"],
["num"=>3,"lett"=>"a"]
];
usort($mtx, function($a,$b) {
if($a['num']<$b['num']) return 1;
if($a['num']>$b['num']) return -1;
});
var_dump($mtx);
/*
array(3) { [0]=> array(2) { ["num"]=> int(3) ["lett"]=> string(1) "a" }
[1]=> array(2) { ["num"]=> int(3) ["lett"]=> string(1) "b" }
[2]=> array(2) { ["num"]=> int(1) ["lett"]=> string(1) "f" }
}
*/
Upvotes: 0
Views: 153
Reputation: 14927
Sorting an array will attempt to sort every item against every other one, so you can't force usort
(which only gives you the values) to maintain the items' original order even if those items are equal.
However, you can make use of uksort
which will give you access to the keys (from the original array) as well, allowing you to fallback to that:
uksort($mtx, function ($key1, $key2) use ($mtx) {
$a = $mtx[$key1];
$b = $mtx[$key2];
if ($a['num'] < $b['num']) {
return 1;
}
if ($a['num'] > $b['num']) {
return -1;
}
return $key1 - $key2;
});
Shorter form:
uksort($mtx, function ($key1, $key2) use ($mtx) {
return $mtx[$key2]['num'] - $mtx[$key1]['num'] ?: $key1 - $key2;
});
Upvotes: 1